浮点数求和结果异常:三种Python求和方法结果不一致
浮点数求和精度问题:pandas sum/循环累加 vs math.fsum
我尝试用三种方法计算一组浮点数的和:pandas sum、for循环累加、math.fsum。结果只有math.fsum得到了预期的100.0,另外两种方法的结果都偏离了预期值。
测试代码
import pandas as pd import math def main(): data = [61.1, 19.3, 15.7, 3.07, .255, .158, .102, .072, .0608, .0048, .0416, .0368, .0288, .0128, .0112, .0096, .0096, .008, .0048, .004, .004, .0032, .0024, .0006] df = pd.DataFrame(data,columns=['value']) print(df['value'].sum()) sum_total = 0 for x in data: sum_total += x print(sum_total) print(math.fsum(data)) main()
当前输出
99.99999999999999 100.00000000000004 100.0
预期输出
100.0 100.0 100.0
原因分析
这是浮点数二进制表示的固有精度问题:
- 大部分十进制小数无法被二进制浮点数精确存储,比如61.1、19.3这类数本身就带有微小的存储误差。
- 普通累加逻辑(for循环、pandas默认sum调用的numpy sum)会逐步累积这些微小误差,最终导致结果偏离预期。
math.fsum采用了补偿求和算法,能在累加过程中跟踪并修正误差,从而得到更精确的结果。
解决方案
- 优先使用高精度求和函数:
- 对列表直接使用
math.fsum(data) - pandas中可以用
df['value'].agg(math.fsum)或numpy.fsum(df['value'])替代默认sum方法
- 对列表直接使用
- 转换为整数计算:
如果所有数值的小数位数固定,可先乘以10的n次方转为整数,求和后再还原:data_int = [int(x * 10000) for x in data] total_int = sum(data_int) print(total_int / 10000) # 输出100.0
内容的提问来源于stack exchange,提问作者beetlej
相关产品推荐
相关产品推荐

