我在Python中的浮点数上遇到模数问题。这段代码:
...
print '(' + repr(olddir) + ' + ' + repr(self.colsize) + ') % (math.pi*2) = ' + repr((olddir+self.colsize)
...
打印:
(6.281876310240881 + 0.001308996938995747) % (math.pi*2) = 2.9043434324194095e-13
我知道浮点数不准确。但我无法理解这一点。
我不知道它是否有任何相关性,但Google Calculator也无法处理此计算。这是Google Calculator的输出:
(6.28187631024 + 0.001308996939) % (pi * 2) = 6.28318531
导致此计算错误的原因是什么?我怎样才能在Python程序中避免它?
答案 0 :(得分:4)
使用str()
打印浮点数实际上会打印数字的圆形版本:
>>> print repr(math.pi)
3.1415926535897931
>>> print str(math.pi)
3.14159265359
因此我们无法真正重现您的结果,因为我们不知道您正在进行计算的确切值。显然,olddir+self.colsize
的确切值略大于2*math.pi
,而您在Google Calculator中使用的舍入值之和略小于2*math.pi
。
答案 1 :(得分:2)
str
和repr
>>> import scipy
>>> pi = scipy.pi
>>> str(pi)
'3.14159265359'
>>> repr(pi)
'3.1415926535897931'
str
将浮点数截断为12位数,其中repr给出内部表示(作为字符串)。
编辑:总而言之,问题出现了,因为你过早地进行了舍入,并通过非常接近它的数字来计算某事物的模数。对于浮点数,舍入不可避免地涉及将十进制数转换为二进制数。
首先,举例说明舍入如何通过实际数学(不是浮点数学)来伤害你。看(3.14 + 3.14)%(3.14 + 3.14),显然为零。现在,如果我们首先将数字四舍五入到一个十进制数字会发生什么?好(3.1 + 3.1)%(3.14 + 3.14)= 6.2%(6.28)= 6.2(谷歌给你的)。或者,如果你做了回合(3.14159,5)+回合(3.14159,5)%(3.14159 + 3.14159)= 6.2832%6.28318 = 2e-5。
因此,通过舍入到N位数(通过使用有效舍入数字的str
),您的计算仅精确到小于N位数。要使这项工作继续进行,必须以更高的数字进行四舍五入(保持两个计算的数字以确保安全)。例如,str在第12位进行,所以也许我们应该在第10位进行舍入。
>>> round(6.28187631024 + 0.001308996939,10) % (round(pi * 2,10))
0