为什么 IDL 默认值看起来是四舍五入的?

发布于 2024-09-05 17:21:27 字数 403 浏览 1 评论 0原文

我有一个 COM 对象,其函数带有可选的最后一个参数。 IDL 有点像这样:

interface ICWhatever: IDispatch
{
  [id(96)] HRESULT SomeFunction([in,defaultvalue(50.6)]float parameter);
};

这工作正常:如果我不指定参数,则填充 50.6。 但在一些开发环境(Excel VBA、VB6)中,默认值在显示前会进行四舍五入。输入左大括号后,我看到:

SomeFunction([参数为单个 = 51])

有谁知道这是为什么?这是一个错误吗?这会让客户端程序员感到困惑......

I have a COM object with a function with an optional last argument. The IDL is a bit like this:

interface ICWhatever: IDispatch
{
  [id(96)] HRESULT SomeFunction([in,defaultvalue(50.6)]float parameter);
};

This works fine: if I don't specify the parameter, 50.6 is filled in.
But in several development environments (Excel VBA, VB6) the default value is rounded before display. After typing the open brace, I see:

SomeFunction([parameter As Single = 51])

Does anyone know why this is? Is it a bug? This will confuse client programmers...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

东京女 2024-09-12 17:21:27

我能够重现您遇到的问题 (VBA),它似乎确实是(特别是)VB IDE 处理 Single 类型时的错误。也就是说,VB IDE 会错误地将 Single 默认值转换为 int,然后再次将其打印为(截断的)单精度浮点数(作为方法签名的一部分) - 点值。

这个问题在Microsoft Script Editor中不存在,在OleView.exe等中也不存在。

要测试,请尝试以下Single默认值值:18446744073709551615.0。就我而言,该值已在 TLB 中正确编码,并由 OleView.exeMicrosoft 脚本编辑器 正确显示为 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,因为 Double 会被转换并正确显示< /strong> 我能够测试的所有 IDE。


在切线上,您可能已经意识到某些浮点值(例如 0.1)没有相应的精确的 IEEE 754 表示,并且无法与其他值区分开来(例如0.1000000015。)因此,指定默认双精度0.1将在大多数IDE中显示为<代码>0.100000001490116。缓解此精度问题的一种方法是为参数选择不同的比例(例如,从秒切换到毫秒,因此 0.1 秒将变为 100 毫秒,明确表示为单精度和双精度浮点,以及整数值/参数。)

I was able to reproduce the problem you experienced (VBA), and it appears to be indeed a bug in the treatment of the Single type by (specifically) VB IDEs. Namely, the VB IDEs will improperly cast the Single default value to int before printing it out again (as part of the method signature) as a (truncated) single-precision floating-point value.

This problem does not exist in the Microsoft Script Editor, nor does it exist in OleView.exe etc.

To test, try the following Single default value: 18446744073709551615.0. In my case, this value is properly encoded in the TLB and properly displayed by OleView.exe and by Microsoft Script Editor as 1.844674E+19. However, it gets displayed as -2.147484E+09 in the VB IDEs. Indeed, casting (float)18446744073709551615.0 to int produces -2147483648 which, displayed as float, produces the observed (incorrect) VB IDE output -2.147484E+09.

Similarly, 50.6 gets cast to int to produce 51, which is then printed out as 51.

To work around this issue use Double instead of Single, as Double is converted and displayed properly by all IDEs I was able to test.


On a tangent, you are probably already aware of the fact that certain floating point values (such as 0.1) do not have a corresponding exact IEEE 754 representation and cannot be distinguished from other values (e.g. 0.1000000015.) Thus, specifying a default double-precision value of 0.1 will be displayed in most IDEs as 0.100000001490116. One way to alleviate this precision issue is to choose a different scale for your parameters (e.g. switch from seconds to milliseconds, thus 0.1 seconds would become 100 milliseconds, unambiguously representable as both single- and double precision floating point, as well as integral values/parameters.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文