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
来自System.pas
varSingle = $0004; { vt_r4 4 }
varDouble = $0005; { vt_r8 5 }
因此,我希望VTSingle是4,而不是5
我错过了什么?
Delphi库选择通过调用_VarFromReal
来实现变量的所有浮点赋值。这个函数看起来是这样的:
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
。并且包括到作为Double
的别名的Real
的隐式转换。我不知道设计师为什么选择那个特定的路线,但这个选择的结果是你观察到的行为。
制作varSingle
变体的一种简单方法可以使用:
VariantSingle := VarAsType(SingleTest, varSingle);
尽管这将把SingleTest
转换成Double
,然后再转换回Single
。
为了避免这种不必要的转换,请编写自己的助手:
function VarFromSingle(const Value: Single): Variant;
begin
VarClear(Result);
TVarData(Result).VSingle := Value;
TVarData(Result).VType := varSingle;
end;
你可以这样称呼它:
VariantSingle := VarFromSingle(SingleTest);
我认为后一种方法是正确的解决办法。