python中可能的整数溢出
我正在完成hackerrank的euler问题1项目。 我写了一个暴力解决方案来检查我的答案。除了输入10^9之外,它似乎是正确的。 我被告知正确答案是: 233333333166666668 我回来了: 2333331636666680python中可能的整数溢出,python,integer,overflow,Python,Integer,Overflow,我正在完成hackerrank的euler问题1项目。 我写了一个暴力解决方案来检查我的答案。除了输入10^9之外,它似乎是正确的。 我被告知正确答案是: 233333333166666668 我回来了: 2333331636666680 n = 1000000000 sum_of_multiples_3 = int((int((n-1)/3.0)+1) * (int((n-1)/3.0)/2.0) * 3) sum_of_multiples_5 = int((int((n-1)/5.0)+1)
n = 1000000000
sum_of_multiples_3 = int((int((n-1)/3.0)+1) * (int((n-1)/3.0)/2.0) * 3)
sum_of_multiples_5 = int((int((n-1)/5.0)+1) * (int((n-1)/5.0)/2.0) * 5)
sum_of_multiples_15 = int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
print(sum_of_multiples_3 + sum_of_multiples_5 - sum_of_multiples_15)
您正在使用浮点除法,其中整数除法将执行以下操作:
int((n-1)/3.0)
更好地表达为
(n-1)//3
e、 g.使用Python的floor division操作符,不要使用float,然后使用floor
当您将浮点运算扩展到极限之外时,使用整数地板除法不会遇到舍入问题
当按下足够大的n
时,可以看到此舍入错误:
>>> n = 100000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
333333316666665
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
333333316666665
>>> n = 1000000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
33333333166666664
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
33333333166666665
额外的1完全是因为您遇到了浮动的限制:
>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0)
2222222211111111.0
>>> ((n-1)//15+1) * ((n-1)//15//2)
2222222211111111
>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15
3.3333333166666664e+16
我不知道你为什么总是从n
中减去一;这根本不需要,而且会导致错误的结果。也许您是在试图补偿浮点舍入错误?正确的公式是:
(((n // 3) + 1) * (n // 3)) // 2 * 3
(((n // 5) + 1) * (n // 5)) // 2 * 5
(((n // 15) + 1) * (n // 15)) // 2 * 15
给我任何n
的正确输出:
>>> n = 1000000000
>>> sum_of_multiples_3 = (((n // 3) + 1) * (n // 3)) // 2 * 3
>>> sum_of_multiples_5 = (((n // 5) + 1) * (n // 5)) // 2 * 5
>>> sum_of_multiples_15 = (((n // 15) + 1) * (n // 15)) // 2 * 15
>>> sum_of_multiples_3 + sum_of_multiples_5 - sum_of_multiples_15
233333334166666668
我会在这里使用一个函数来计算倍数:
def sum_of_multiples(n, k):
k_in_n = n // k
return ((k_in_n + 1) * k_in_n) // 2 * k
因此,您可以通过与蛮力求和进行比较来验证它是否有效:
>>> sum(range(0, 10000 + 1, 3)) == sum_of_multiples(10000, 3)
True
>>> sum(range(0, 10000 + 1, 5)) == sum_of_multiples(10000, 5)
True
>>> sum(range(0, 10000 + 1, 15)) == sum_of_multiples(10000, 15)
True
然后用它来计算答案:
>>> sum_of_multiples(n, 3) + sum_of_multiples(n, 5) - sum_of_multiples(n, 15)
233333334166666668
您正在使用浮点除法,其中整数除法将执行以下操作:
int((n-1)/3.0)
更好地表达为
(n-1)//3
e、 g.使用Python的floor division操作符,不要使用float,然后使用floor
当您将浮点运算扩展到极限之外时,使用整数地板除法不会遇到舍入问题
当按下足够大的n
时,可以看到此舍入错误:
>>> n = 100000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
333333316666665
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
333333316666665
>>> n = 1000000000
>>> int((int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15)
33333333166666664
>>> ((n-1)//15+1) * ((n-1)//15//2) * 15
33333333166666665
额外的1完全是因为您遇到了浮动的限制:
>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0)
2222222211111111.0
>>> ((n-1)//15+1) * ((n-1)//15//2)
2222222211111111
>>> (int((n-1)/15.0)+1) * (int((n-1)/15.0)/2.0) * 15
3.3333333166666664e+16
我不知道你为什么总是从n
中减去一;这根本不需要,而且会导致错误的结果。也许您是在试图补偿浮点舍入错误?正确的公式是:
(((n // 3) + 1) * (n // 3)) // 2 * 3
(((n // 5) + 1) * (n // 5)) // 2 * 5
(((n // 15) + 1) * (n // 15)) // 2 * 15
给我任何n
的正确输出:
>>> n = 1000000000
>>> sum_of_multiples_3 = (((n // 3) + 1) * (n // 3)) // 2 * 3
>>> sum_of_multiples_5 = (((n // 5) + 1) * (n // 5)) // 2 * 5
>>> sum_of_multiples_15 = (((n // 15) + 1) * (n // 15)) // 2 * 15
>>> sum_of_multiples_3 + sum_of_multiples_5 - sum_of_multiples_15
233333334166666668
我会在这里使用一个函数来计算倍数:
def sum_of_multiples(n, k):
k_in_n = n // k
return ((k_in_n + 1) * k_in_n) // 2 * k
因此,您可以通过与蛮力求和进行比较来验证它是否有效:
>>> sum(range(0, 10000 + 1, 3)) == sum_of_multiples(10000, 3)
True
>>> sum(range(0, 10000 + 1, 5)) == sum_of_multiples(10000, 5)
True
>>> sum(range(0, 10000 + 1, 15)) == sum_of_multiples(10000, 15)
True
然后用它来计算答案:
>>> sum_of_multiples(n, 3) + sum_of_multiples(n, 5) - sum_of_multiples(n, 15)
233333334166666668
Python中没有整数溢出。您可能有浮点舍入错误..我得到:233333331666668…我得到233333331666668是因为我的错误。我的n少了一个零。请尝试再次运行它。Python中没有整数溢出。您可能有浮点舍入错误..我得到:233333331666668…我得到233333331666668是因为我的错误。我的n少了一个零。再次尝试运行它。当我这样做时,我得到一个n=200的不同结果:
((n-1)//5)+1)*((n-1)//5)/2.0)*5
,当我这样做时:((n-1)//5)+1)*((n-1)//5)*5
@zetologos:不要从n
中减去1,也不要除以浮点值。你想把部门划分成一个整体,所以使用//2
Awesome。非常感谢你,看起来不错。但我需要的结果是排他性的,而不是包容性的。例如:print(sum([i代表i在范围(5200,5)])
No,欧拉问题已经包含了n
。当我这样做时,我得到了n=200的不同结果:((n-1)//5)+1)*((n-1)//5)/2.0)*5
((n-1)//5)*((n-1)//zetolo:,不要除以浮点值。你想把部门划分成一个整体,所以使用//2
Awesome。非常感谢你,看起来不错。但我需要的结果是排他性的,而不是包容性的。示例:print(sum([i代表范围(5200,5)])
No,Euler问题已包含在内。