18

(int)(33.46639 * 1000000)返回33466389

为什么会这样?

4

7 回答 7

31

浮点数学并不完美。 每个程序员都应该知道的。

许多人认为浮点运算是一门深奥的学科。这是相当令人惊讶的,因为浮点在计算机系统中无处不在。几乎每种语言都有浮点数据类型;从个人电脑到超级计算机的计算机都有浮点加速器;大多数编译器将不时被要求编译浮点算法;几乎每个操作系统都必须响应浮点异常,例如溢出。本文介绍了对计算机系统设计者有直接影响的浮点方面的教程。它从浮点表示和舍入误差的背景开始,继续讨论 IEEE 浮点标准,并以计算机制造商如何更好地支持浮点的大量示例结束。

...

将无限多个实数压缩为有限位数需要近似表示。尽管整数有无限多,但在大多数程序中,整数计算的结果可以存储在 32 位中。相反,给定任何固定位数,大多数实数计算将产生无法使用那么多位精确表示的量。因此,浮点计算的结果必须经常四舍五入以适应其有限表示。这种舍入误差是浮点计算的特征。

于 2010-03-11T01:55:09.830 回答
5

双精度不精确,所以内部 33.46639 实际上存储为 33.466389

编辑:正如理查德所说,它是浮点数据,(以二进制形式存储在一组有限的位中)所以不完全是这样)......

于 2010-03-11T01:54:44.627 回答
3

1994 年底是新年前夜。英特尔首席执行官安迪·格鲁夫 (Andy Grove) 迎来了美好的一年,奔腾处理器问世并大获成功。于是,他走进一家酒吧,点了两杯尊尼获加绿牌。

酒保端上来,说:“先生,那是 20 美元。”

格鲁夫将一张二十美元的钞票放在柜台上,看了一会儿,说:“留下零钱。”

http://en.wikipedia.org/wiki/Pentium_FDIV_bug

于 2010-03-11T02:59:13.330 回答
2

原因是 33.46639 将被表示为略小于该数字的值。

乘以 1000000 将得到 33466389.99999999。

使用 (int) 进行类型转换将只返回整数部分 (33466389)。

如果您想要“正确”的数字,请在类型转换之前尝试 round()。

于 2010-03-11T01:59:49.020 回答
1

因为 33.46639 不能用有限的二进制数字精确表示。33.46639 * 1000000 的实际结果是 33466389.9999999962747097015380859375。演员表将其截断为 33466389。

于 2010-03-11T02:23:09.623 回答
1

如果你问为什么它没有变成33466390,那是因为doubles 没有无限精度,并且数字不能精确地用二进制表示。

如果将 替换doubledecimal( (int)(33.46639m * 1000000)),则等于33466390,因为decimals 是以 10 为基数计算的。

于 2010-03-11T01:55:55.307 回答
-1

你得到不同结果的原因是你使用了'演员'

(int)(33.46639 * 1000000) 返回 33466389
^^^^^

将结果转换为“int”类型......当它们相乘时向上或向下舍入整数类型,然后转换为“int”......不要依赖浮点来足够准确...... .Skeet 在他的网站herehere上发布了精彩的介绍...

于 2010-03-11T01:55:32.263 回答