写程序时遇到 0.1 + 0.2 !== 0.3,或者财务计算里多出几毛钱的误差?这不是你的代码写错了,是浮点数在底层就‘天生不精确’——但别急,有些办法确实能让它更靠谱。
为啥浮点数老不准?
计算机用二进制存小数,而像 0.1 这样的十进制小数,在二进制里是无限循环小数(就像 1/3 在十进制里是 0.333…),只能截断存储。IEEE 754 标准下的 float64 类型,最多也就约 16 位有效数字,超出部分直接舍掉。
换数据类型:decimal 比 float 更稳
做金额、科学测量这类对精度敏感的场景,优先用 decimal 类型。Python 的 decimal 模块、Java 的 BigDecimal、C# 的 decimal 都是十进制定点/浮点实现,不依赖二进制近似。
from decimal import Decimal, getcontext
getcontext().prec = 28 # 设定精度为28位
a = Decimal('0.1')
b = Decimal('0.2')
print(a + b) # 输出:0.3,不是 0.30000000000000004避免累积误差:重排计算顺序
多个小浮点数相加时,从小到大排序再加,比从大到小或乱序加更稳。因为大数吃掉小数的风险更低。比如累加一组含 1e-10 和 1e5 的数,先加小的再逐步合并,误差明显减小。
用整数代替小数:能转就转
处理钱,别存 19.99 元,直接存 1999 分;处理温度到 0.01℃,就存成整数毫摄氏度。运算全在整数域完成,最后才除以 100 或 1000 输出。既快又准,连四舍五入都可控。
高精度库不是万能药
像 Python 的 mpmath 或 C++ 的 Boost.Multiprecision 确实能设几百位精度,但速度慢、内存高,日常开发中很少需要。真要算圆周率十万位?可以;但算个商品折扣价?纯属杀鸡用牛刀。
调试时别信 print,信 repr
Python 中 print(0.1) 显示 0.1,其实是格式化后的假象;用 repr(0.1) 才能看到真实值:'0.1000000000000000055511151231257827021181583404541015625'。调试精度问题,务必用 repr 或 format(x, '.17g') 看真相。