有几个关于浮点表示法的问题被提交给了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 ...
这些数字也没有任意的限制。位置向左和向右无限增加。
这是个好问题。
你所有的问题都是基于“我们如何表示一个数字?”
所有的数字都可以用十进制表示,也可以用二进制(2的补码)表示。所有人!!
但有些(大多数)需要无穷多个元素(二进制位置为“0”或“1”,十进制表示为“0”,“1”到“9”)。
比如十进制表示的1/3(1/3 = 0.3333333…<-包含无限个“3”)
比如二进制中的0.1 (0.1 = 0.00011001100110011....<-带有无限个“0011”)
一切都在这个概念中。由于您的计算机只能考虑有限的数字集(十进制或二进制),只有一些数字可以准确地表示在您的计算机…
乔恩说过,3是质数,不是10的因数,所以1/3不能用以10为底的有限个数来表示。
即使使用任意精度的算术,以2为基数的编号位置系统也不能完全描述6.1,尽管它可以表示61。
对于6.1,我们必须使用另一种表示法(比如十进制表示法,或者允许以2为底或以10为底表示浮点值的IEEE 854)。
例如,数字61.0具有精确的二进制表示,因为任何数字的整数部分总是精确的。但6.10这个数字并不准确。我所做的只是把小数点移了一位突然间我就从精确乌托邦变成了不精确镇。从数学上讲,这两个数字之间不应该有本质差别——它们只是数字。
让我们暂时撇开以10为底和以2为底的细节。我们问一下,在以b为底的情况下,哪些数字有终止表示,哪些数字没有?稍微思考一下,我们就知道一个数字x有一个终止的b表示,当且仅当存在一个整数n,使得x b^n是一个整数。
例如,x = 11/500有一个终止10表示,因为我们可以选择n = 3,然后x b^n = 22,一个整数。但是x = 1/3不是,因为不管n取多少都不能消掉3。
第二个例子促使我们思考因子,我们可以看到,对于任何有理数x = p/q(假设是最小值),我们可以通过比较b和q的质因数分解来回答这个问题。如果q有任何不在b的质因数分解中的质因数,我们将永远无法找到一个合适的n来摆脱这些因数。
因此,对于以10为底的任何p/q,其中q有除2或5之外的素数因子,将没有终止表示。
现在回到以10和2为底,我们看到任何以10为底的有理数都是p/q的形式当q的质因数分解中只有2s和5s时;当q的质因数分解中只有2时,同样的数会有一个终止的2表示。
但其中一个案例是另一个案例的子集!每当
Q的质因数分解只有2
这显然也是正确的
Q的质因数分解只有2和5
换句话说,只要p/q有终止的2表示,p/q就有终止的10表示。然而反过来就不成立了——只要q的质因数分解中有一个5,它就会有一个终止的10表示,而不是终止的2表示。这是其他答案提到的0.1的例子。
这就是问题的答案了因为2的质因数是10的质因数的子集,所以所有以2结尾的数都是以10结尾的数,反之则不然。不是61比6.1,而是10比2。
最后提醒一下,如果有些人使用17进制,而我们的计算机使用5进制,你的直觉永远不会被这引入歧途——在这两种情况下都不会有(非零,非整数)数字终止!