【发布时间】:2013-10-21 15:15:32
【问题描述】:
免责声明:我知道 0.025 不能在 IEEE 浮点变量中精确表示,因此,舍入可能不会返回预期的结果。那不是我的问题!
是否可以在 .NET 中模拟 VBA 算术运算符的行为?
例如,在 VBA 中,以下表达式产生 3:
Dim myInt32 As Long
myInt32 = CLng(0.025 * 100) ' yields 3
但是,在 VB.NET 中,以下表达式产生 2:
Dim myInt32 As Integer
myInt32 = CInt(0.025 * 100) ' yields 2
根据规范,两者都应该返回相同的值:
- Long (VBA) 和 Integer (VB.NET) 是 32 位整数类型。
- 根据the VBA specification,CLng 对 Long 执行 Let-coercion,数字类型之间的 Let-coercion 使用 Banker 的舍入。 The same is true 用于 VB.NET 的 CInt。
-
0.025在这两种情况下都是双精度 IEEE 浮点常量。
因此,浮点乘法运算符或整数转换运算符的一些实现细节发生了变化。但是,出于与旧版 VBA 系统兼容的原因,我需要在 .NET 应用程序中复制 VBA 的数学行为(尽管它可能是错误的)。
有没有办法做到这一点?有人写了Microsoft.VBA.Math 库吗?还是 precise VBA 算法记录在某处,以便我自己做?
【问题讨论】:
-
VBA/VBScript/VB6 确实按照您在学校的教学方式进行了四舍五入,0.5 一直在上升。在 DotNet 中,他们转向了真正的数学四舍五入,一次向上一次向下,在计算平均值时为您提供更准确的数字。如果你想像 VBA 那样四舍五入,你需要考虑使用 FLOOR 或 CEILING。
-
@Steve:不。 VBA 规范明确提到 VBA 使用 Banker 的舍入,这与 .NET 使用的完全相同。在 VBA 中尝试
CLng(0.035 * 100)和CLng(0.045 * 100)进行比较。 -
看来
*在 VBA 与 .NET 中返回不同的结果:2.5 - 0.025*100 = -1.38777878078145E-16 在 VBA,0 在 .NET。 -
@MichaelLiu:是的,但这可能是 VBA 编译器优化的结果:请注意,
2.5 - CDbl(0.025*100)在 VBA 中产生0。 (对于双打,CDbl 应该是 NO-OP。) -
@varocarbas - 否决投票是匿名的,您无法确定谁 否决了您。显然有两个人(与 OP 或任何回答者无关)出于某种原因不喜欢您的回答。无论如何,您的回答确实没有解决 Heinzi 的主要问题。