为什么(int)(33.46639 * 1000000)返回33466389?

时间:2010-03-11 01:52:17

标签: c# floating-point floating-accuracy multiplication

(int)(33.46639 * 1000000)返回33466389

为什么会这样?

7 个答案:

答案 0 :(得分:31)

浮点数学并不完美。 What every programmer should know关于它。

  

浮点运算被很多人认为是一个深奥的主题。这是相当令人惊讶的,因为浮点在计算机系统中无处不在。几乎每种语言都有浮点数据类型;从PC到超级计算机的计算机都有浮点加速器;大多数编译器都会被要求不时编译浮点算法;几乎每个操作系统都必须响应溢出等浮点异常。本文提供了一个关于浮点的方面的教程,这些方面对计算机系统的设计者有直接影响。它首先介绍浮点表示和舍入误差,继续讨论IEEE浮点标准,最后总结了许多计算机构建器如何更好地支持浮点数的例子。

     

...

     

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

答案 1 :(得分:5)

双精度不准确,因此内部33.46639实际存储为33.466389

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

答案 2 :(得分:3)

这是1994年底的新年前夜。英特尔首席执行官安迪·格鲁夫(Andy Grove)迎来了一个伟大的一年,奔腾(Pentium)处理器的出现让人大受欢迎。所以,他走进一家酒吧,并下令Johnnie Walker绿色标签的双重镜头。

酒保服了起来说,“这将是20美元,先生。”

格罗夫在柜台上放了一张二十美元的钞票,看了一会儿,说道,“保持改变。”

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

答案 3 :(得分:2)

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

乘以1000000将为您提供33466389.99999999。

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

如果你想要“正确”号码,请在输入前尝试round()。

答案 4 :(得分:1)

如果你问为什么它不会变成33466390,那是因为double没有无限精度,而且这个数字不能用二进制表示。

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

答案 5 :(得分:1)

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

答案 6 :(得分:-1)

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

(int)(33.46639 * 1000000) returns 33466389
^^^^^

将结果转换为'int'类型...当将多个一起向上或向下舍入整数类型然后转换为'int'时....不要依赖浮点就足够准确.... Skeet在他的网站herehere ...

上发布了一篇精彩的介绍