(int)(33.46639 * 1000000)
返回33466389
为什么会这样?
浮点数学并不完美。 每个程序员都应该知道的。
许多人认为浮点运算是一门深奥的学科。这是相当令人惊讶的,因为浮点在计算机系统中无处不在。几乎每种语言都有浮点数据类型;从个人电脑到超级计算机的计算机都有浮点加速器;大多数编译器将不时被要求编译浮点算法;几乎每个操作系统都必须响应浮点异常,例如溢出。本文介绍了对计算机系统设计者有直接影响的浮点方面的教程。它从浮点表示和舍入误差的背景开始,继续讨论 IEEE 浮点标准,并以计算机制造商如何更好地支持浮点的大量示例结束。
...
将无限多个实数压缩为有限位数需要近似表示。尽管整数有无限多,但在大多数程序中,整数计算的结果可以存储在 32 位中。相反,给定任何固定位数,大多数实数计算将产生无法使用那么多位精确表示的量。因此,浮点计算的结果必须经常四舍五入以适应其有限表示。这种舍入误差是浮点计算的特征。
双精度不精确,所以内部 33.46639 实际上存储为 33.466389
编辑:正如理查德所说,它是浮点数据,(以二进制形式存储在一组有限的位中)所以不完全是这样)......
1994 年底是新年前夜。英特尔首席执行官安迪·格鲁夫 (Andy Grove) 迎来了美好的一年,奔腾处理器问世并大获成功。于是,他走进一家酒吧,点了两杯尊尼获加绿牌。
酒保端上来,说:“先生,那是 20 美元。”
格鲁夫将一张二十美元的钞票放在柜台上,看了一会儿,说:“留下零钱。”
原因是 33.46639 将被表示为略小于该数字的值。
乘以 1000000 将得到 33466389.99999999。
使用 (int) 进行类型转换将只返回整数部分 (33466389)。
如果您想要“正确”的数字,请在类型转换之前尝试 round()。
因为 33.46639 不能用有限的二进制数字精确表示。33.46639 * 1000000 的实际结果是 33466389.9999999962747097015380859375。演员表将其截断为 33466389。
如果你问为什么它没有变成33466390
,那是因为double
s 没有无限精度,并且数字不能精确地用二进制表示。
如果将 替换double
为decimal
( (int)(33.46639m * 1000000)
),则等于33466390
,因为decimal
s 是以 10 为基数计算的。