java中0.0/0.0返回nan,1.0/0.0返回infinity,符合ieee 754标准;nan不等于自身,须用double.isnan()判断;infinity需用double.isinfinite()检测;整数除零仍抛arithmeticexception。

Java中0.0 / 0.0和1.0 / 0.0到底返回什么
它们不抛异常,而是分别返回NaN和Infinity——这是IEEE 754浮点标准强制要求的行为,JVM必须遵守。
常见错误现象:用==直接比较NaN,比如Double.NaN == Double.NaN结果是false;或者把Infinity当普通大数参与Math.max(),却没意识到它可能来自意外的除零。
-
0.0 / 0.0→NaN(Not-a-Number),表示未定义的数学结果 -
1.0 / 0.0→Infinity(正无穷),-1.0 / 0.0→-Infinity - 整数除零(如
1 / 0)仍会抛ArithmeticException,只有浮点数才走IEEE路径
判断NaN和Infinity的正确写法
不能用==或.equals(),因为NaN不等于任何值(包括自己),而Double.POSITIVE_INFINITY.equals()在某些旧JDK版本有坑。
必须用JDK内置的静态方法:
立即学习“Java免费学习笔记(深入)”;
- 判
NaN:用Double.isNaN(x)或Float.isNaN(x),这是唯一可靠方式 - 判无穷:用
Double.isInfinite(x)(同时捕获正负无穷),若需区分方向,再配合x > 0 - 别写
x == Double.NaN,它永远是false;也别依赖new Double(x).equals(Double.NaN),包装类缓存和null风险多一层绕
NaN和Infinity在集合与JSON中的表现
它们能存进ArrayList<double></double>、HashMap键值,但行为反直觉:两个NaN视为“相等”用于contains(),但HashSet里可能因哈希码不同重复插入。
更实际的问题在序列化:
- Fastjson默认把
NaN序列化成null,Infinity直接报错;Jackson默认拒绝二者,需显式配置JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS或自定义序列化器 - 数据库JDBC层通常不支持
NaN/Infinity,PostgreSQL会转成NULL,MySQL可能截断或报错,入库前务必校验 - 日志打印时,
System.out.println(Double.NaN)输出NaN,但某些监控系统解析日志字段会失败
为什么Math.abs(-0.0)返回0.0却不是“等于”-0.0
这是IEEE 754里“负零”的遗留设计:-0.0 == 0.0为true,但Double.doubleToLongBits(-0.0) != Double.doubleToLongBits(0.0)——位模式不同。
影响真实场景:
- 涉及符号敏感计算时(如复数运算、极限方向判断),
-0.0和0.0会导致不同结果,比如1.0 / -0.0是-Infinity - 用
==做条件分支看似安全,但若后续用Double.doubleToRawLongBits()做缓存key,-0.0和0.0会映射到不同槽位 - 多数业务代码可以忽略负零,但金融或科学计算库必须显式处理
Math.copySign(1.0, x)来提取符号位
浮点数的边界行为从来不是“理论问题”,而是上线后凌晨三点查日志时发现的NaN扩散链——从一个未校验的除零,到缓存命中率归零,再到下游JSON解析失败。盯住isNaN()和isInfinite()这两个检查点,比事后追数据流省力得多。










