我正在尝试编写一个程序来查找给定n以下所有3的倍数的总和。到目前为止,我想出了这个解决方案(使用算术级数公式):
def sumof3(n):
n = int((n-1)/3)
return int((n/2)*(6+3*(n-1)))
它工作得很好,但由于某种原因开始大量失败。例如,对于 n = 232471924,返回值是 9007199280122284,而它应该是 9007199280122283。
有人可以建议这里的错误在哪里吗?
我正在尝试编写一个程序来查找给定n以下所有3的倍数的总和。到目前为止,我想出了这个解决方案(使用算术级数公式):
def sumof3(n):
n = int((n-1)/3)
return int((n/2)*(6+3*(n-1)))
它工作得很好,但由于某种原因开始大量失败。例如,对于 n = 232471924,返回值是 9007199280122284,而它应该是 9007199280122283。
有人可以建议这里的错误在哪里吗?
Python 有任意精度的整数,但有标准的有限(双)精度浮点数。在 Python 3 中,两个整数除以/
产生一个浮点数,这意味着(例如)
>>> 10**50/10**25
1e+25
>>> int(10**50/10**25)
10000000000000000905969664
但如果我们使用 纯粹处理整数//
,我们会得到:
>>> 10**50//10**25
10000000000000000000000000
在您的代码中,两者都(n-1)/3
将(n/2)
产生浮点输出,这意味着您只有大约 18 位左右的精度。如果我们将您的函数重新设计为纯粹使用整数:
def sumof3b(n):
n = (n-1)//3
return (6+3*(n-1))*n//2
然后我们就低值达成一致:
>>> all(sumof3(n) == sumof3b(n) for n in range(10**7))
True
但在高值下,我们保持精度:
>>> n = 232471924
>>> sumof3(n) # bad
9007199280122284
>>> sumof3b(n) # good
9007199280122283
[在这里我们可以重新排序以确保我们不会丢失任何小数数据,但我有时会发现该fractions
模块也很方便。]
这是一个舍入错误的示例:
将无限多个实数压缩为有限位数需要近似表示。尽管整数有无限多,但在大多数程序中,整数计算的结果可以存储在 32 位中。相反,给定任何固定位数,大多数实数计算将产生无法使用那么多位精确表示的量。因此,浮点计算的结果必须经常四舍五入以适应其有限表示。这种舍入误差是浮点计算的特征。
通过执行以下操作,您将足够接近您想要的位置:
def sumof3(n):
n = float((n-1)/3)
return int((n/2)*(6+3*(n-1)))
或者,如果您想更精确:
def sumof3(n):
n = float((n-1)/3)
return float((n/2)*(6+3*(n-1)))
它太大了int
import sys
print int(sys.maxint)
print int(sys.maxint*2)
对我来说它打印
2147483647
-2
糊弄我!误解了问题!对不起!