系列之和。这个Python代码有什么问题?

时间:2014-10-23 15:38:44

标签: python debugging sum-of-digits

我正在尝试编写一个程序来查找给定n下面所有3的倍数之和。 到目前为止,我想出了这个解决方案(使用算术系列公式):

def sumof3(n):
    n = int((n-1)/3)
    return int((n/2)*(6+3*(n-1)))

它运作良好,但由于某种原因开始失败大数。例如,对于n = 232471924 返回值为9007199280122284,而应为9007199280122283。

有人可以告知这里的错误在哪里吗?

3 个答案:

答案 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)

这是round-off error

的示例
  

将无限多个实数压缩成有限数量的位需要近似表示。尽管存在无限多个整数,但在大多数程序中,整数计算的结果可以以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这个问题!遗憾!