我正在尝试编写一个程序来查找给定n下面所有3的倍数之和。 到目前为止,我想出了这个解决方案(使用算术系列公式):
def sumof3(n):
n = int((n-1)/3)
return int((n/2)*(6+3*(n-1)))
它运作良好,但由于某种原因开始失败大数。例如,对于n = 232471924 返回值为9007199280122284,而应为9007199280122283。
有人可以告知这里的错误在哪里吗?
答案 0 :(得分:3)
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
模块也派上用场。]
答案 1 :(得分:0)
将无限多个实数压缩成有限数量的位需要近似表示。尽管存在无限多个整数,但在大多数程序中,整数计算的结果可以以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)))
答案 2 :(得分:0)
这对于int
来说太大了
import sys
print int(sys.maxint)
print int(sys.maxint*2)
对我来说它打印
2147483647
-2
傻了我! Misunderstud这个问题!遗憾!