Project Euler第1题:大数下3和5的倍数求和方案失效排查
Project Euler第1题大数计算偏差问题分析
你的代码在处理极大输入值时出现结果偏差,核心问题是浮点数精度丢失。
问题根源
你在计算等差数列和时使用了除法/,这会将运算结果转换为浮点数。Python的双精度浮点数仅能保留约15-17位有效数字,当n极大时,last_num_3、last_num_5这类数值会非常大,远超浮点数的精确表示范围,导致计算过程中出现精度损失,最终转成整数时就会得到错误结果。
比如当last_num_3是一个超过16位的整数时,(3+last_num_3)/2无法精确表示为浮点数,后续乘法运算会进一步放大误差。
修复方案
改用纯整数运算完成等差数列求和,避免浮点数参与。等差数列求和公式(首项 + 末项) * 项数 // 2中的所有运算都可以用整数实现,完全不会有精度问题:
import math def sec_sol(n): last_num_3 = (n-1) - ((n-1) % 3) last_num_5 = (n-1) - ((n-1) % 5) last_num_15 = (n-1) - ((n-1) % 15) # 先做乘法再用整数除法//2,全程避免浮点数 sums_of_3 = (3 + last_num_3) * math.floor(last_num_3 / 3) // 2 sums_of_5 = (5 + last_num_5) * math.floor(last_num_5 / 5) // 2 sums_of_15 = (15 + last_num_15) * math.floor(last_num_15 / 15) // 2 return sums_of_3 + sums_of_5 - sums_of_15
进一步优化
由于last_num_3是3的倍数,math.floor(last_num_3 / 3)等价于last_num_3 // 3,用整数除法替代浮点数转换,代码更简洁高效:
def sec_sol(n): last_num_3 = (n-1) - ((n-1) % 3) last_num_5 = (n-1) - ((n-1) % 5) last_num_15 = (n-1) - ((n-1) % 15) sums_of_3 = (3 + last_num_3) * (last_num_3 // 3) // 2 sums_of_5 = (5 + last_num_5) * (last_num_5 // 5) // 2 sums_of_15 = (15 + last_num_15) * (last_num_15 // 15) // 2 return sums_of_3 + sums_of_5 - sums_of_15
内容的提问来源于stack exchange,提问作者ne0123.
相关产品推荐
相关产品推荐

