繁体   English   中英

浮点表示似乎正确地进行整数运算 - 为什么?

[英]Floating point representations seem to do integer arithmetic correctly - why?

我一直在玩浮点数,根据我过去对它们的了解, 0.1 + 0.2最终变成0.30000000000000004事实并不让我感到惊讶。

什么让我感到吃惊,但是,是整数运算似乎总是工作得很好,并没有这些文物。

我首先在JavaScript中注意到这一点(node.js中的Chrome V8):

0.1 + 0.2 == 0.3 // false, NOT surprising
123456789012 + 18 == 123456789030  // true
22334455667788 + 998877665544 == 23333333333332 // true
1048576 / 1024 == 1024  // true

C ++(Mac OS X上的gcc)似乎具有相同的属性。

最终的结果似乎是整数,只是 - 缺乏一个更好的词 - 工作 只有当我开始使用十进制数字时,事情变得不稳定。

这是设计的特征,数学工件,还是编译器和运行时环境所做的一些优化?

这是设计的特征,数学工件,还是编译器和运行时环境所做的一些优化?

这是实数的一个特征。 现代代数(现代代数,不是高中代数;数学专业在基本微积分和线性代数类之后在现代代数中取一类)的定理说,对于某些正整数b ,任何正实数r都可以表示为r = a * b p ,其中a在[1, b )中, p是某个整数。 例如,1024 10 = 1.024 10 * 10 3 正是这个定理证明了我们使用科学记数法是正确的。

该数字a可以被分类为终端(例如1.0),重复(1/3 = 0.333 ......)或非重复(pi的表示)。 这里有终端号码的小问题。 任何终端号码也可以表示为重复数字。 例如,0.999 ...和1是相同的数字。 可以通过指定可以表示为终端号的数字如此表示来解决表示中的这种模糊性。

您发现的是所有整数在任何基数中都具有终端表示的结果。

这里有一个关于如何在计算机中表示实数的问题。 就像intlong long int不代表所有整数一样, floatdouble也不代表所有的实数。 在大多数计算机上用来表示实数r的方案是以r = a * 2 p的形式表示,但是尾数(或有效数) 截断为一定数量的位并且指数p限于某个有限数。 这意味着某些整数无法准确表示。 例如,即使googol(10 100 )是一个整数,它的浮点表示也不准确。 googol的基数2表示是333位数。 该333位尾数被截断为52 + 1位。

这样做的结果是双精度算术不再精确,即使对于整数,如果所讨论的整数大于2 53 在2 53和2 64之间的值上使用unsigned long long int类型尝试您的实验。 您会发现对于这些大整数,双精度算术不再精确。

我写的是假设Javascript对所有数字使用双精度浮点表示。

一些数字具有浮点格式的精确表示,特别是所有整数,如|x| < 2^53 |x| < 2^53 某些数字尤其不是诸如0.1或0.2的分数,其在二进制表示中变为无限分数。

如果所有操作数和操作结果都具有精确表示,那么使用==比较结果是安全的。

相关问题:

二进制数中的数字只能表示为近似值?

为什么十进制数不能用二进制表示?

具有可表示范围的整数可由机器准确表示,浮点数不是(嗯,大多数)。

如果通过“基本整数数学”你理解“特征”,那么是的,你可以假设正确实现算术是一个特征。

原因是,您可以完全以二进制格式(0001,0010,0011,...)表示每个整数(1,2,3,...)

这就是为什么整数总是正确的,因为0011 - 0001总是为0010.浮点数的问题是,点之后的部分不能精确地转换为二进制。

您说“工作”的所有情况都是您给出的数字可以用浮点格式精确表示的情况。 您会发现添加0.25和0.5以及0.125也可以正常工作,因为它们也可以精确地表示为二进制浮点数。

它只是不能达到0.1的值,你会得到看似不精确的结果。

整数是准确的,因为不精确的结果主要来自我们写小数部分的方式,其次是因为许多有理数在任何给定的基数中都没有非重复的表示。

有关完整说明,请参阅: https//stackoverflow.com/a/9650037/140740

只有当你向一个非常大的整数添加一个足够小的整数时,该方法才有效 - 即使在这种情况下,你也不能以“浮点”格式表示两个整数。

无法表示所有浮点数。 这是由于编码方式。 维基页面比我更好地解释了它: http//en.wikipedia.org/wiki/IEEE_754-1985 因此,当您尝试比较浮点数时,应使用delta:

myFloat - expectedFloat < delta

您可以使用最小的可表示浮点数作为delta。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM