为什么在varDouble变体中为变量分配单个结果?

TmT*_*ron 8 delphi variant

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.
Run Code Online (Sandbox Code Playgroud)

上面的代码将输出:

VarType:单身:5,双人5

来自System.pas

varSingle   = $0004; { vt_r4           4 }
varDouble   = $0005; { vt_r8           5 }
Run Code Online (Sandbox Code Playgroud)

因此,我希望VTSingle是4 - 而不是5
我错过了什么?

Dav*_*nan 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;
Run Code Online (Sandbox Code Playgroud)

请注意,这使用了一种类型varDouble.并包含一个隐式转换,Real其中包含别名Double.我不确定为什么设计师会选择那条特定的路线,但这种选择的结果就是你观察到的行为.

制作varSingle可以使用的变体的简单方法:

VariantSingle := VarAsType(SingleTest, varSingle);
Run Code Online (Sandbox Code Playgroud)

虽然这会转换SingleTestDouble,然后再回到Single.

要避免那种不必要的转换,请编写自己的帮助器:

function VarFromSingle(const Value: Single): Variant;
begin
  VarClear(Result);
  TVarData(Result).VSingle := Value;
  TVarData(Result).VType := varSingle;
end;
Run Code Online (Sandbox Code Playgroud)

您可以这样调用:

VariantSingle := VarFromSingle(SingleTest);
Run Code Online (Sandbox Code Playgroud)

在我看来,后一种方法是正确的解决方案.