为什么将单个分配给变量会导致varDouble变量? [英] Why does assigning a single to a variant result in a varDouble variant?

查看:107
本文介绍了为什么将单个分配给变量会导致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

VarType: Single: 5, Double 5

从System.pas

From System.pas

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

因此,我希望VTSingle为 4 -而不是5
我想念什么?

Thus, I'd expect VTSingle to be 4 - not 5
What am I missing?

推荐答案

Delphi库选择通过调用_VarFromReal来实现对变量的所有浮点分配.该函数如下所示:

The Delphi libraries choose to implement all floating point assignments to variants by means of a call to _VarFromReal. And that function looks like this:

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的别名.我不确定为什么设计师会选择这种特定的路线,但是这种选择的结果就是您观察到的行为.

Note that this uses a type of varDouble. And includes an implicit conversion to Real which is an alias for Double. I'm not sure why the designers chose that particular route, but the consequence of that choice is the behaviour that you observe.

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

A simple way to make a varSingle variant you can use:

VariantSingle := VarAsType(SingleTest, varSingle);

尽管这会将SingleTest转换为Double,然后再次转换回Single.

Although this will convert SingleTest to Double, and then back again to Single.

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

To avoid that needless conversion, write your own helper:

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

您可以这样称呼:

VariantSingle := VarFromSingle(SingleTest);

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

This latter approach is the correct solution in my opinion.

这篇关于为什么将单个分配给变量会导致varDouble变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆