为什么将单个变量赋值给变量会导致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

来自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);

我认为后一种方法是正确的解决办法。

相关内容

  • 没有找到相关文章

最新更新