我有一个带有可选最后一个参数的函数的COM对象。 IDL有点像这样:
interface ICWhatever: IDispatch
{
[id(96)] HRESULT SomeFunction([in,defaultvalue(50.6)]float parameter);
};
这很好用:如果我没有指定参数,则填入50.6。 但是在几个开发环境(Excel VBA,VB6)中,默认值在显示之前被舍入。输入开括号后,我看到:
SomeFunction( [参数为单身= 51 ] )
有谁知道这是为什么?这是一个错误吗?这会让客户程序员感到困惑......
答案 0 :(得分:1)
我能够重现您遇到的问题(VBA),并且它似乎确实通过(特定)VB IDE 处理Single
类型的错误。也就是说,VB IDE会将Single
默认值不正确地转换为int
,然后再将其打印出来(作为方法签名的一部分)作为(截断的)单精度浮点值。
Microsoft脚本编辑器中不存在此问题,OleView.exe
等也不存在此问题。
要进行测试,请尝试以下Single
默认值:18446744073709551615.0
。在我的情况下,此值在TLB中正确编码,并由OleView.exe
和 Microsoft脚本编辑器正确显示为1.844674E+19
。但是,它在VB IDE中显示为-2.147484E+09
。实际上,将(float)18446744073709551615.0
转换为int
会生成-2147483648
,显示为float
,会生成观察到的(不正确的)VB IDE输出-2.147484E+09
。
同样,50.6
会被投射到int
以生成51
,然后将其打印为51
。
要解决此问题,请使用Double
代替Single
,因为所有IDE都会转换Double
并正确显示 我能够测试。
在切线上,您可能已经意识到某些浮点值(例如0.1
)没有相应的精确的 IEEE 754表示,而不能区别于其他值(例如0.1000000015
。)因此,指定0.1
的默认双精度值将在大多数IDE中显示为0.100000001490116
。缓解此精度问题的一种方法是为参数选择不同的比例(例如,从秒切换到毫秒,因此0.1
秒将变为100
毫秒,无法明确表示为单精度和双精度浮动点,以及积分值/参数。)