单位选择对数值精度的影响——Python科学计算技术问询
单位选择对科学计算数值精度的影响
根源:Python用的IEEE 754双精度浮点数特性
Python里的普通浮点数都是双精度IEEE 754格式,这三点直接决定了单位选择的重要性:
- 只能精确表示2^53以内的整数(约9000万亿),超出这个范围的整数会丢失末尾有效位;
- 像0.1、1e-9这类十进制非整数,转换成二进制是无限循环的,存入计算机只能是近似值;
- 浮点数的有效数字约15-17位,但数值量级偏离1越远,加减运算时的精度损失风险越高。
单位选择到底能带来什么影响?
1. 让整数运算完全精确
如果能把数值转换成双精度可精确存储的整数,运算就不会有任何精度损失。比如:
- 1nm=10埃,两者都是整数,用nm或埃做单位,乘、减等运算结果完全精确;
- 但换成米的话,1nm=1e-9米,1e-9是二进制近似值,哪怕简单乘法,底层存储都会有微小误差(虽然打印出来可能还是1.0)。
看Python示例:
# 用米计算10亿个1nm的总和 sum_m = 1e-9 * 10**9 print(sum_m == 1.0) # 表面返回True,但sum_m是近似值,并非严格等于1.0 # 用nm计算10亿个1nm的总和 sum_nm = 1 * 10**9 print(sum_nm == 10**9) # 绝对True,1e9在2^53范围内,完全精确 # 转成米也无误差 print(sum_nm * 1e-9 == 1.0) # True,1e9*1e-9是精确的1.0
2. 避免小数值被大数值“吞噬”
浮点数加减时,若两个数量级差过大,小数的有效位会直接被忽略。选对单位能让参与运算的数值尽量处于同一量级:
- 比如计算1e6米 + 1nm,用米运算的话,
1e6 + 1e-9结果还是1e6——因为1e6的最小可分辨增量约为2.27e-7,1e-9远小于这个值,加了等于没加; - 换成nm运算则是
1e12 nm + 1 nm = 1000000000001 nm,这个数在2^53范围内,可精确存储,转成米就是准确的1000000.000000001米。
3. 防止数值直接“消失”或溢出
- 下溢:若数值过小,比如用米表示原子半径(约1e-10米),多次相乘后可能直接变成0,完全丢失数据;换成埃的话就是1埃,怎么运算都不会轻易归零;
- 上溢:若数值过大,比如用埃计算地球到太阳的距离(1.5e21埃),虽未溢出,但计算星系间距离时会很快超过浮点数最大值(1.8e308)变成
inf,导致运算失效;换成光年或米则不会有这个问题。
实际开发建议
- 优先选择能让核心运算数值接近1,或可转成2^53以内整数的单位;
- 遇到跨量级加减,先统一到中间量级,不要直接用大数加小数;
- 对精度要求极高的场景,可使用
decimal模块做十进制精确运算,但会牺牲一定性能; - 调试时可查看浮点数的极限参数:
import sys print(sys.float_info.min) # 最小可存储的正浮点数 print(sys.float_info.max) # 最大可存储的浮点数 print(sys.float_info.epsilon)# 1.0与下一个可存储浮点数的差值
内容的提问来源于stack exchange,提问作者Rafid Bendimerad
相关产品推荐
相关产品推荐

