【发布时间】:2016-09-30 19:48:06
【问题描述】:
rate : Currency;
mod1 : Currency;
mod2 : Currency;
mod_rate : Currency;
rate := 29.90;
mod1 := 0.95;
mod2 := 1.39;
mod_rate := rate * mod1 * mod2;
如果您在计算器上执行此计算,您会得到39.45295 的值。由于 Delphi 的 Currency 数据类型仅精确到小数点后 4 位,因此它在内部对值进行四舍五入。我的测试表明它使用了银行家的四舍五入,因此 mod_rate 应该包含 39.4530 的值,但是在这种特殊情况下它会截断为 39.4529。
我有 40,000 个这样的计算,除了上面的以外,所有的都是正确的。这是一个四舍五入的例子:
rate := 32.25;
mod1 := 0.90;
mod2 := 1.15;
这等于在计算器上的33.37875,根据银行家的四舍五入将转到33.3788,这就是德尔福所做的。
有人能解释一下 Delphi 在这里做什么吗?
【问题讨论】:
-
我的猜测是 39.4595 不能完全用浮点表示。舍入没有错,但可表示性。使用十进制算术而不是货币。
-
货币是定点数据类型。除非将两种货币相乘产生一个浮点数。
-
@Chet:
Currency值在内部存储为 64 位整数,这些整数乘以 10000 以去除小数,但对Currency值执行的数学运算对这些整数使用浮点数学指令。 -
您可以在此处查看 39.45295 的浮点表示:What is the exact value of a floating-point variable?。扩展精度值低于 39.45295,因此向下舍入。
-
看看Decimals,这是一个以更高的精度处理浮点值的库,尽管是以性能为代价的。