strictmath 保证跨平台结果完全一致,math 不保证;strictmath 基于 fdlibm 并遵循 ieee 754,禁用扩展精度;math 可启用硬件指令与 jit 优化,中间精度可能致结果差 1 ulp。

StrictMath 和 Math 在不同平台下对同一计算的输出是否一致,关键看“结果可复现性”是否被强制保障——StrictMath 保证一致,Math 不保证。
StrictMath:跨平台结果完全确定
StrictMath 所有数学方法(包括 sqrt、sin、pow 等)均基于 fdlibm 库实现,并严格遵循 IEEE 754 标准。它用 strictfp 修饰,禁用浮点中间结果的扩展精度,确保:
- 在 x86、ARM、RISC-V 等任意 CPU 架构上,输入相同,输出比特位完全一致
- Windows、Linux、macOS、嵌入式 JVM 上运行结果逐位相同
- 即使 JVM 实现不同(如 OpenJDK、Zulu、GraalVM),只要版本支持 StrictMath,结果不变
Math:优先性能,允许平台差异
Math 类多数方法默认调用 StrictMath,但 JVM 可以且通常会启用优化路径:
- 利用 CPU 的硬件指令(如 x86 的
fsqrt、ARM 的vsqrt.f64)加速 sqrt 计算 - 启用 JIT 内联或 intrinsic 替换(例如
Math.sqrt()在 HotSpot 中常被编译为单条机器指令) - 中间浮点运算可能使用扩展精度(如 80 位 x87 寄存器),导致极少数输入下结果与 StrictMath 差 1 ULP(最后一位有效数字)
实际影响哪些场景?
差异通常只在高精度敏感或长期可复现要求的场景中显现:
- 金融系统:利率复利、期权定价模型需多平台验证一致,应选 StrictMath
- 科学仿真/测试断言:单元测试中依赖固定浮点输出(如 assertEqual(Math.sqrt(2), 1.4142135623730951)),用 StrictMath 更可靠
- 区块链或共识逻辑:节点间必须达成完全一致的数值结果,StrictMath 是事实标准
- 普通业务开发:UI 计算、分页总数、简单单位换算等,Math 足够快也足够准,无需切换
如何验证你环境中的差异?
可快速运行对比代码观察:
double x = 123456789.123456789;
System.out.println("Math.sqrt: " + Math.sqrt(x));
System.out.println("StrictMath.sqrt: " + StrictMath.sqrt(x));
// 若两行输出在不同机器上不完全一致(尤其老旧 ARM 或某些 JDK 版本),说明 Math 正在使用平台优化










