浮点模数问题

发布于 2024-11-06 18:57:54 字数 512 浏览 3 评论 0原文

我在 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 计算器的输出:

(6.28187631024 + 0.001308996939) % (pi * 2) = 6.28318531

是什么导致了此计算错误?我怎样才能在我的Python程序中避免这种情况呢?

I'm having a problem with modulus on a floating point number in Python. This code:

...
print '(' + repr(olddir) + ' + ' + repr(self.colsize) + ') % (math.pi*2) = ' + repr((olddir+self.colsize)
...

Prints:

(6.281876310240881 + 0.001308996938995747) % (math.pi*2) = 2.9043434324194095e-13

I know floating point numbers aren't precise. But I can't get this to make any sense.

I don't know if it is in any way related but Google Calculator can't handle this calculation either. This is the output from Google Calculator:

(6.28187631024 + 0.001308996939) % (pi * 2) = 6.28318531

What is causing this calculation error? And how can I avoid it in my Python program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

焚却相思 2024-11-13 18:57:54

使用 str() 打印浮点数实际上会打印该数字的舍入版本:

>>> print repr(math.pi)
3.1415926535897931
>>> print str(math.pi)
3.14159265359

因此我们无法真正重现您的结果,因为我们不知道您正在计算的确切值和。显然,olddir+self.colsize 的精确值略大于 2*math.pi,而您在 Google 计算器中使用的舍入值的总和略小比2*math.pi

Using str() to print a floating point number actually prints a rounded version of the number:

>>> print repr(math.pi)
3.1415926535897931
>>> print str(math.pi)
3.14159265359

So we can't really reproduce your results, since we don't know the exact values you are doing the computation with. Obviously, the exact value of olddir+self.colsize is slightly greater than 2*math.pi, while the sum of the rounded values you used in Google Calculator is slightly less than 2*math.pi.

苹果你个爱泡泡 2024-11-13 18:57:54

strrepr 之间的区别

>>> 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 (谷歌给你的)。或者,如果您执行 round(3.14159,5) + round(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

The difference between str and repr

>>> import scipy
>>> pi = scipy.pi
>>> str(pi)
'3.14159265359'
>>> repr(pi)
'3.1415926535897931'

str truncates floating point numbers to 12 digits, where repr gives the internal representation (as a string).

EDIT: So in summary, the problem arose because you rounded prematurely and are calculating the modulus of something via a number that's very close to it. With floating point numbers, rounding is inevitably involved in converting decimal numbers into binary.

First, do an example of how rounding hurts you with actual math (not floating point math). Look at (3.14+3.14) % (3.14+3.14), which is obviously zero. Now what would happen if we rounded the digits to one decimal digit first on one side? Well (3.1+3.1) % (3.14+3.14) = 6.2 % (6.28) = 6.2 (what google gave you). Or if you did round(3.14159,5) + round(3.14159,5) % (3.14159 + 3.14159) = 6.2832 % 6.28318 = 2e-5.

So in by rounding to N digits (by using str which effectively rounds the numbers), your calculation is only accurate to less than N digits. To have this work going forward force rounding at some higher digit (keeping two calculated digits for safety) is necessary. E.g., str rounds at digit 12, so maybe we should round at digit 10.

>>> round(6.28187631024 + 0.001308996939,10) % (round(pi * 2,10))
0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文