有几个关于浮点表示法的问题被提交给了SO。例如,十进制数0.1没有精确的二进制表示,因此使用==操作符将其与另一个浮点数进行比较是危险的。我理解浮点表示法背后的原理。

我不明白的是,为什么从数学的角度来看,小数点右边的数字比左边的数字更“特殊”?

例如,数字61.0具有精确的二进制表示,因为任何数字的整数部分总是精确的。但6.10这个数字并不准确。我所做的只是把小数点移了一位突然间我就从精确乌托邦变成了不精确镇。从数学上讲,这两个数字之间不应该有本质差别——它们只是数字。

相比之下,如果我把小数点向另一个方向移动一位,得到数字610,我仍然在Exactopia。我可以继续往这个方向(6100,610000000,610000000000000)它们仍然是完全,完全,完全的。但是一旦小数点越过某个阈值,这些数字就不再精确了。

这是怎么呢

编辑:为了澄清,我不想讨论诸如IEEE之类的行业标准表示,而是坚持我所相信的数学上的“纯粹”方式。以10为基数,位置值为:

... 1000  100   10    1   1/10  1/100 ...

在二进制中,它们将是:

... 8    4    2    1    1/2  1/4  1/8 ...

这些数字也没有任意的限制。位置向左和向右无限增加。


当前回答

一个简单的答案是:计算机没有无限的内存来存储分数(在以科学记数法的形式表示十进制数之后)。根据IEEE 754双精度浮点数标准,我们只有53位的限制来存储分数。 欲了解更多信息:http://mathcenter.oxford.emory.edu/site/cs170/ieee754/

其他回答

重复一下我在给斯基特先生的评论中所说的话:我们可以用十进制表示1/3、1/9、1/27或任何有理数。我们通过添加一个额外的符号来实现。例如,在数字的十进制展开中重复的数字上的一行。将十进制数表示为二进制数序列所需要的是1)一个二进制数序列,2)一个基数点,以及3)一些其他符号来表示序列的重复部分。

赫纳的引用符号就是一种方法。他用引号表示序列中重复的部分。文章地址:http://www.cs.toronto.edu/~hehner/ratno.pdf,维基百科词条:http://en.wikipedia.org/wiki/Quote_notation。

并没有说我们不能在表示系统中添加一个符号,所以我们可以用二进制引号表示十进制有理数,反之亦然。

一个简单的答案是:计算机没有无限的内存来存储分数(在以科学记数法的形式表示十进制数之后)。根据IEEE 754双精度浮点数标准,我们只有53位的限制来存储分数。 欲了解更多信息:http://mathcenter.oxford.emory.edu/site/cs170/ieee754/

我不想重复其他20个答案的总结,所以我只简单地回答:

答案在你的内容中:

为什么以两为基数的数字不能精确地表示一定的比率?

出于同样的原因,小数不足以表示某些比率,即分母中包含除2或5之外的素数因子的不可约分数,至少在其小数展开的尾数中总是有一个不确定的字符串。

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

This question at face value is based on a misconception regarding values themselves. No number system is sufficient to represent any quantity or ratio in a manner that the thing itself tells you that it is both a quantity, and at the same time also gives the interpretation in and of itself about the intrinsic value of the representation. As such, all quantitative representations, and models in general, are symbolic and can only be understood a posteriori, namely, after one has been taught how to read and interpret these numbers.

由于模型是主观的东西,在反映现实的范围内是正确的,我们不需要严格地将二进制字符串解释为2的负幂和正幂的和。相反,我们可以观察到,我们可以创建一组任意的符号,这些符号以2为基底或任何其他基底来精确地表示任何数字或比例。只要考虑一下,我们可以用一个词甚至一个符号来指代无穷大,而不需要“显示无穷大”本身。

As an example, I am designing a binary encoding for mixed numbers so that I can have more precision and accuracy than an IEEE 754 float. At the time of writing this, the idea is to have a sign bit, a reciprocal bit, a certain number of bits for a scalar to determine how much to "magnify" the fractional portion, and then the remaining bits are divided evenly between the integer portion of a mixed number, and the latter a fixed-point number which, if the reciprocal bit is set, should be interpreted as one divided by that number. This has the benefit of allowing me to represent numbers with infinite decimal expansions by using their reciprocals which do have terminating decimal expansions, or alternatively, as a fraction directly, potentially as an approximation, depending on my needs.

这和你不能精确地以10为基数表示1/3的原因是一样的,你需要说0.33333(3)。在二进制中,这是相同类型的问题,只是发生在不同的数字集上。

上面的高分答案完全正确。

首先,你的问题中混合了以2为底和以10为底的数,然后当你把一个不能整除的数放在右边时,你就有问题了。比如十进制的1/3因为3不能整除10的幂,或者二进制的1/5不能整除2的幂。

Another comment though NEVER use equal with floating point numbers, period. Even if it is an exact representation there are some numbers in some floating point systems that can be accurately represented in more than one way (IEEE is bad about this, it is a horrible floating point spec to start with, so expect headaches). No different here 1/3 is not EQUAL to the number on your calculator 0.3333333, no matter how many 3's there are to the right of the decimal point. It is or can be close enough but is not equal. so you would expect something like 2*1/3 to not equal 2/3 depending on the rounding. Never use equal with floating point.