我期待到舍入浮在Python点数和下面的行为似乎很奇怪:
代码 :
a = 203.25
print '%.2f'%(a/10.)
print '%.2f'%(round(a/10., 2))
print '%.2f'%(0.1*a)
输出 :
20.32
20.32
20.33
为什么第一,尤其是第二种情况下会失败?
我期待到舍入浮在Python点数和下面的行为似乎很奇怪:
代码 :
a = 203.25
print '%.2f'%(a/10.)
print '%.2f'%(round(a/10., 2))
print '%.2f'%(0.1*a)
输出 :
20.32
20.32
20.33
为什么第一,尤其是第二种情况下会失败?
http://en.wikipedia.org/wiki/Rounding#Round_half_to_even
回合一半甚至
一个平局决胜规则是较少偏见是圆的一半甚至 ,即:如果y的分数为0.5,则q是偶数整数最接近为y。 因此,例如,23.5变为24一样,24.5; 而-23.5变为-24一样,-24.5。
此方法对称地对待正值和负值,并且因此无符号的偏见。 更重要的是,对于y值的合理分布,圆形数的预期的(平均)值是相同的原始数字。 然而,这条规则将出台向零偏压为偶数,并且向无穷偏向奇数的。
圆到最近方法的这种变体也被称为偏舍入,收敛舍入,统计学家的舍入,荷兰四舍五入,高斯圆,奇偶舍入或银行家的舍入 ,并且被广泛用于记账。
这是在IEEE 754计算的函数和操作中使用的默认舍入模式。
>>> "%.2f"%20.325
'20.32'
>>> "%.2f"%20.335
'20.34'
>>> "%.2f"%20.345
'20.34'
>>> "%.2f"%20.355
'20.36'
所以,真正的问题应该是,为什么第三个案例失败?
203.25
可以精确地用浮点表示来表示,但是0.1
不能,它原来是大于一点点0.1
>>> 0.1*203.25
20.325000000000003
因此,它被围捕
这可能是答案的一部分:
>>> a*.1
20.325000000000003
>>> a/10
20.325
请参阅有关IEEE 754舍入是如何实现的@gnibblers解释。
我不知道为什么如预期的情况下不工作的具体细节,但如果你想与你的花车严格的准确性,使用类似十进制模块 。
没有失败。 见什么每个程序员应该知道关于浮点运算 。
你可以用printf来看看发生了什么
print '%0.20f'%20.325
20.32499999999999928946
对于Python文档round()
指向的答案。 基本上,浮点不能完全代表一些数字 。 例如, 0.1
最终看起来像0.10000000000000001
。 这不精确性有时会导致意想不到的结果。 这真的很困难得到宽容的给定范围内计算浮点数。 究其原因, 0.1 * a
计算工作在你的情况,是因为它是四舍五入的所需方向有一点点偏差。
如果你真的需要的精度,你应该看看使用十进制模块 。 与十进制数的工作也可以是件苦差事,但它确实使它有点更容易得到你想要的精确度。