为什么我不能乘以浮动?

可能重复:
处理浮点数中的精度问题

我很惊讶为什么我试图将C中的浮点数(与GCC 3.2)相乘并且它没有按照我的预期进行。作为示例:

int main() { float nb = 3.11f; nb *= 10; printf("%f\n", nb); } 

显示:31.099998

我对浮动的实现方式及其产生这种意外行为的原因感到好奇吗?

首先,你可以繁殖浮动。 你遇到的问题不是乘法本身,而是你使用的原始数字。 乘法可能会失去一些精确度,但是这里您乘以的原始数字始于精度损失。

这实际上是一种预期的行为。 float s使用二进制表示来实现,这意味着它们无法准确地表示十进制值。

有关更多信息,请参阅MSDN 。

您还可以在浮点描述中看到它具有6-7个有效数字的精度。 在你的例子中,如果你将31.09999831.099998到7位有效数字,你将得到31.1所以它仍然按预期工作。

double类型当然会更准确,但由于它的二进制表示仍然有舍入误差,而你写的数字是十进制的。

如果想要十进制数的完全准确性,则应使用十进制类型。 此类型存在于C#等语言中。 http://msdn.microsoft.com/en-us/library/system.decimal.aspx

您还可以使用有理数表示。 使用两个整数,只要您可以将数字表示为两个整数的除法,就可以提供完整的精度。

这是按预期工作的。 计算机具有有限的精度,因为它们试图从整数计算浮点值。 这导致浮点不准确。

浮点维基百科页面详细介绍了表示和产生的精度问题,而不是我在这里:)

有趣的现实世界的注意事项: 这也是使用整数(美分)进行大量金钱计算的部分原因 – 不要让计算机因缺乏精确度而亏本! 我想要我的$ 0.00001!

数字3.11不能用二进制表示。 24位有效位最接近的是11.0001110000101000111101,小数点为3.1099998950958251953125。

如果您的数字3.11应该代表货币金额,那么您需要使用小数表示。

在Python社区中,我们经常看到人们对此感到惊讶,因此有关于该问题的经过充分测试和调试的常见问题解答和教程部分 (当然,它们是用Python而不是C语言表达的,但是因为Python代表浮点运算无论如何,对于底层C和硬件,浮点机制的所有描述仍然适用)。

当然,这不是乘法的错误 – 删除你乘以nb的语句,无论如何你都会看到类似的问题。

来自维基百科的文章 :

事实上,浮点数不能精确地表示所有实数,并且浮点运算不能精确地表示真正的算术运算,这会导致许多令人惊讶的情况。 这与计算机通常表示数字的有限精度有关。

浮点不精确,因为它们使用基数2(因为它是二进制:0或1)而不是基数10.而基数2转换为基数10,正如之前所说的那样,将导致舍入精度问题。