标签:
半年前,偶然留意到一个奇怪的现象 1/3*3=1 而 0.333...*3=0.999... ,当中差了一个非常小的数 0.000...1。一直百思不得其解。
而最近发现更为离奇的是,2/5+3/5=1,0.4+0.6=1,这个在十进制中完美无懈,但是转换到二进制后(人工转换,不存在计算机符点数不精确的问题)
十进制分数 | 十进制小数 | 二进制分数 | 二进制小数 |
1/5 | 0.2 | 1/101 | 0.001100110011... |
2/5 | 0.4 | 10/101 | 0.0110011001100... |
3/5 | 0.6 | 11/101 | 0.1001100110011.. |
4/5 | 0.8 | 100/101 | 0.110011001100... |
5/5 | 1.0 | 101/101 | 0.111... 还是 1.0 ?? |
这就是一个很奇怪的问题了,为什么相同的数转换成小数后,不同的进制居然会出现不同的结果。那是不是说人类如果是以八进制或者十六进制的,那跟现在的十进制的科技发展都不一样了??我们知道,十进制中,除数只含2和5因数的能够除尽,即不产生无限循环小数。而如果是二进制,则除数只含2才能除尽。(这里原因是跟小数点的移位相关,请自行百度不具体展开讲)这样的话不同的进制,就因为有的化为有限,有的化为无限,同样的数加起来结果却不相同。
同样的道理我们再回到1/3与0.333...的问题上,如果是使用三进制的话,1/3直接就等于0.1了,3*0.1=1却完全正确。问题到底出在哪里呢?
一步步来debug,我们先来看看 1/3化为小数0.333...这一步有没有问题。怎么看呢?我们日常的除法转换步骤因为太习以常了,很难发现其中有没有bug。那么就从结果反推吧
0.333... = 0.3+0.03+0.003+...+0.00...3
= 3/10+3/100+...+3/10n
= 3*(1/10+1/100+1/1000+...1/10n)
= 3*( 10n-1/10n + 10n-2/10n + 10n-3/10n + ... +100/10n)
= 3*( ((10n - 1)/9 )/10n ) 等比求和公式
= 1/3 * (1-1/10n)
= 1/3 - 1/(3*10n) (n→∞)
意外地发现,原来0.333...其实并不等于1/3,也就是说我们在分数转换成小数的时候,对于无限循环小数的省约写法其实是有误差的!
具体误差在哪里?那就再仔细把小学学的除法演算一遍:
1÷3 = 0.9÷3 + 0.1÷3
= 0.3 + 0.1÷3 = 0.3+(0.09+0.01)÷3
= 0.33 + 0.01÷3 = 0.33+(0.009+0.001)÷3
= 0.333 + 0.001÷3
= 。。。
而我们在除法取无限循环小数的时候,其实只是取了前半部分,后面的那项却被忽略了,后面那项是什么呢?仔细观察你会发现其实就是1/10n÷3 (n→∞)。
通过反推和正推,都发现确实是有bug存在。所以 3*0.333... = 0.999... 其实是 3*[1/3 - 1/(3*10n)] = 1-1/10n (n→∞)
这样就间接说明了0.999...≠1,而0.999... 与1所相差的 0.00...1 其实就是 1/10n (n→∞)
可能有人会问 1/10n(n→∞)是否等于0呢?最简单粗暴1/10n * 10n = 1,而0乘以任何数都等于0不可能等于1,所以1/10n不是0。当然还有千百种严谨的方法可以证明 1/10n 不是0 ,这个就请自行查阅了。
回顾到不同进制下数字的不同的问题,其实是并没有问题,都是在转换成小数的时候人为所产生的误差而已。
有意思地在网上发现另外一些看法,并给出了看似无懈可击的反例。
1)大卫·福斯特·华莱士(David Foster Wallace)在他的 《Everything and More》一书中介绍了另外一个著名的证明:
令 x = 0.999...所以 10x = 9.999...两式相减得 9x = 9所以 x = 1
而 9.999... 等于 10-1/10n , 这两者明显不相等,第二个所以就已经错了,最终结果当然也法得来。
2)”x 不等于 y 等价于存在一个z严格介于x和y之间“
0.999...与1之间有没有存在介于两者之间的值呢?化成极限表达式来看看,1-(1/10n) 与 1之间有没有,随手就能举一抄出来(把分母加大),中间是有无限个。那为什么从小数的形式没有看到呢?因为这已经在十进制小数的精度约束下了。为什么这么说呢?要是而弄成十六进制还有A到F呢。十六进制的0.FFF...,有没有比十进制的0.999...更接近1?要是100进制呢,更大的进制呢?
如果你十分确信1/10n(n→∞)就是 0 ,那么以上讨论对你都没有说服力。但是这样的话就相当于确认了从分数到无限小数(如1/3 --> 0.333...) 的转化之间的 人为误差 对实际结果是没有任何影响的。而且等于说,1/0这样的数是存在的,还能出现 0 * 1/0 = 1 这样的乘法计算。疯狂的世界,谁知道呢?
标签:
原文地址:http://www.cnblogs.com/batsing/p/0_999.html