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:Single:5,Double 5
来自System.pas
varSingle = $0004; { vt_r4 4 }
varDouble = $0005; { vt_r8 5 }
因此,我希望VTSingle 4 - 而不是5 我错过了什么?
答案 0 :(得分: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
类型。并且包含对Real
的隐式转换,Double
是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);
你可以像这样打电话:
{{1}}
在我看来,后一种方法是正确的解决方案。