Saturday, May 12, 2007

Python Float

python 浮点

python IDLE中敲入

>>> 0.1
0.10000000000000001

>>> round(1.0/3, 2)
0.33000000000000002
>>> round(11.0/3, 2)
3.6699999999999999

注意所有的编程语言都有这个问题。这是浮点数在计算机中的存储问题。

考虑十进制是0.125这个小数,其二进制表示为0.001,这两个数是完全等同的。
但是不是所有的小数都有这样的特性,大多数的小数不能用二进制精确的表示,其结果就是,所有十进制小数在计算机中都是用其最最近似的方式存储表示的。
考虑分数1/3,可以用十进制近似成0.3,或者0.33,或者0.333。
注:小数部分由十进制转二进制的方法就是一直去掉整数部分,小数部分乘2,直到小数部分为0为止。
如:0.625转为二进制:
0.625*2 = 1.25, 整数部分为1,小数部分为0.25
0.25 * 2 = 0.5 , 整数部分为0,小数部分为0.5
0.5 * 2 = 1 , 整数部分为1,小数部分为0
所以0.625转为二进制的结果就是0.101
但是,有些小数,如0.2,再怎么乘2,小数部分也不会得到0的,所以,就有误差了。
因此,考虑小数0.1,它不能用二进制精确的表示,而是表示成了:
0.0001100110011001100110011001100110011001100110011...  所以你才看到了最开始的情况:
>>> 0.10.10000000000000001
  注意当没有使用print时,python解释器使用repr方法获得它需要显示的对象的字符串形式,对浮点数来说,
repr(float)取到小数点后17位;如果使用print,调用的是str方法:
>>> print 0.1
0.1
  使用round方法并不能取得预期效果,是因为0.10000000000000001已经是1/10的最近似的数了,它总是
取最好的结果。
再看一个示例:
>>> sum=0.0
>>> for i in range(10):
sum+= 0.1

>>> sum
0.99999999999999989
  很多的浮点数运算有这样类似的“奇怪”结果。
  解决办法是使用python的decimal模块:
>>> 0.1*0.5
0.050000000000000003
>>> from decimal import *
>>> Decimal("0.1")*Decimal("0.5")
Decimal("0.05")
  这个模块的功能也比较全面和强大。不予详细说明。

No comments: