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

时间:2013-02-28 10:46:41

标签: 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.

上面的代码将输出:

  

VarType:Single:5,Double 5

来自System.pas

varSingle   = $0004; { vt_r4           4 }
varDouble   = $0005; { vt_r8           5 }

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

1 个答案:

答案 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的隐式转换,DoublevarSingle的别名。我不确定为什么设计师会选择那条特定的路线,但这种选择的结果就是你观察到的行为。

制作可以使用的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}}

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