Java浮点数算术除法的运算结果误差是否始终不超过1 ULP?
Java浮点数除法ULP误差问题解答
核心结论
Java规范强制要求浮点数除法的运算结果误差最大为0.5 ULP,不存在误差达到2 ULP的情况,你的直觉是正确的,基础除法的精度远高于Math类中部分方法的1 ULP误差要求。
相关细节说明
- 首先《Java虚拟机规范》对
float、double两类浮点类型的基础算术运算(加减乘除、求余)有强制精度要求:所有运算结果必须做最近舍入处理,即取距离精确值最近的可表示浮点值,只有当精确值恰好落在两个可表示值正中间时才取偶数低位的那个值,这种规则下误差最大不会超过0.5 ULP,和底层CPU的实现逻辑无关,JVM会负责兜底保证结果符合规范。 - 你提到的部分CPU用
a * 1/b的方式实现除法的情况,分为两种处理:要么这类CPU本身对倒数计算+乘法的组合做了特殊优化,最终输出结果和直接做除法的最近舍入结果完全一致,没有额外误差;要么JVM会在这类CPU上禁用这种快速实现,改用其他保证精度的方式完成除法运算,不会放任误差累积。 - 你假设的“1/b误差1 ULP+乘法误差1 ULP,总误差2 ULP”是最坏情况的独立误差叠加假设,但实际这两步的误差不是独立的,不会直接叠加,而且即使底层硬件真的出现这种误差,JVM也会做修正,不会把不符合规范的结果返回给上层Java代码。
- 你提到的
Math.pow这类方法的1 ULP误差要求是宽松于基础算术运算的,Math类的很多非基础运算因为实现复杂度高,才放宽了精度要求,基础算术运算作为所有浮点计算的底座,精度要求必然更高。
内容的提问来源于stack exchange,提问作者Will Kanga
相关产品推荐
相关产品推荐

