为什么将单个分配给变量会导致varDouble变量?
uses
SysUtils, Variants;
var
VariantSingle: Variant;
VTSingle: TVarType;
SingleTest: Single;
VariantDouble: Variant;
DoubleTest: Double;
VTDouble: TVarType;
begin
SingleTest := 1.234;
VariantSingle := SingleTest;
VTSingle := VarType(VariantSingle) and varTypeMask;
DoubleTest := 1.23456;
VariantDouble := DoubleTest;
VTDouble := VarType(VariantDouble) and varTypeMask;
WriteLn(Format('VarType: Single: %d, Double %d', [VTSingle, VTDouble]));
end.
上面的代码将输出:
VarType:单身:5,双身5
VarType: Single: 5, Double 5
从System.pas
From System.pas
varSingle = $0004; { vt_r4 4 }
varDouble = $0005; { vt_r8 5 }
因此,我希望VTSingle为 4 -而不是5
我想念什么?
Thus, I'd expect VTSingle to be 4 - not 5
What am I missing?
Delphi库选择通过调用_VarFromReal
来实现对变量的所有浮点分配.该函数如下所示:
The Delphi libraries choose to implement all floating point assignments to variants by means of a call to _VarFromReal
. And that function looks like this:
procedure _VarFromReal(var V: TVarData; const Value: Real);
begin
if (V.VType and varDeepData) <> 0 then
VarClearDeep(V);
V.VType := varDouble;
V.VDouble := Value;
end;
请注意,这使用的是varDouble
类型.并且包括对Real
的隐式转换,这是Double
的别名.我不确定为什么设计师会选择这种特定的路线,但是这种选择的结果就是您观察到的行为.
Note that this uses a type of varDouble
. And includes an implicit conversion to Real
which is an alias for Double
. I'm not sure why the designers chose that particular route, but the consequence of that choice is the behaviour that you observe.
可以使用一种简单的方法来制作varSingle
变体:
A simple way to make a varSingle
variant you can use:
VariantSingle := VarAsType(SingleTest, varSingle);
尽管这会将SingleTest
转换为Double
,然后再次转换回Single
.
Although this will convert SingleTest
to Double
, and then back again to Single
.
为避免不必要的转换,请编写您自己的帮助器:
To avoid that needless conversion, write your own helper:
function VarFromSingle(const Value: Single): Variant;
begin
VarClear(Result);
TVarData(Result).VSingle := Value;
TVarData(Result).VType := varSingle;
end;
您可以这样称呼:
VariantSingle := VarFromSingle(SingleTest);
后一种方法在我看来是正确的解决方法.
This latter approach is the correct solution in my opinion.