Math.abs() 对负数返回正数但类型不变,因它按输入类型返回对应类型值;唯独 Integer.MIN_VALUE 因补码限制,abs 后仍为负,即 -2147483648。

Math.abs() 处理负数时为什么返回正数但类型没变
因为 Math.abs() 不改变原始变量类型,只按规则翻转符号:对 int 返回 int,long 返回 long,float 和 double 同理。唯一例外是 Integer.MIN_VALUE 这种边界值——它取绝对值后仍为负,因为补码表示下没有对应的正数可表示。
常见错误现象:Math.abs(Integer.MIN_VALUE) 结果还是 -2147483648,不是正数。
- 使用场景:做安全的差值比较(比如
Math.abs(a - b) ),但要注意输入是否可能为极小值 - 如果必须保正,先转
long再调用:Math.abs((long) Integer.MIN_VALUE) -
Math.abs(float)和Math.abs(double)会保留 NaN 和 Infinity 行为,NaN 输入仍返回 NaN
Math.sin() / Math.cos() 的参数单位容易被当成角度
Java 的三角函数一律以弧度为单位,不是角度。传入 90 得到的是 sin(90 弧度),约等于 0.894,而不是你想要的 1.0。
常见错误现象:计算直角三角形边长时结果明显偏离预期,debug 发现传了 Math.sin(30) 却没加转换。
立即学习“Java免费学习笔记(深入)”;
- 角度转弧度用
Math.toRadians(30),别手写30 * Math.PI / 180(虽然等价,但可读性和维护性差) - 反向转换用
Math.toDegrees(),比如把Math.asin(0.5)的结果转成角度显示 - 所有三角函数对
NaN或无穷大输入都返回NaN,不抛异常,容易掩盖上游数据问题
Math.random() 生成 [0.0, 1.0) 区间浮点数的坑
Math.random() 返回的是 double 类型、左闭右开区间,即包含 0.0,但永远不等于 1.0。它底层用的是 new Random().nextDouble(),线程安全但性能一般,不适合高频调用。
常见错误现象:想生成 [1, 6] 的随机整数,写成 (int)(Math.random() * 6) + 1 是对的;但若写成 (int)(Math.random() * 6 + 1) 就错了——括号位置导致结果范围变成 [1, 6] 实际没问题,但逻辑易混淆;更严重的是有人误以为能生成 1.0 去做边界判断。
- 需要指定范围整数时,优先用
ThreadLocalRandom.current().nextInt(1, 7)(Java 7+),更快且线程友好 - 要生成
[a, b]的 double,用a + Math.random() * (b - a),注意是b - a,不是b - a + 1 -
Math.random()每次调用都新建Random实例(旧版本),新 JDK 已优化,但仍不如复用Random实例或ThreadLocalRandom
Math.pow() 计算整数幂时精度丢失和性能问题
Math.pow(double, double) 是通用浮点幂函数,内部用指数/对数实现,对整数幂(如 2^10)既慢又可能有微小误差——比如 Math.pow(10, 2) 可能返回 99.99999999999999,转 int 就变 99。
常见错误现象:循环中反复调用 Math.pow(2, i) 做位运算替代,结果在某次迭代突然出错。
- 整数幂优先用位运算:
1 替代 <code>Math.pow(2, n)(仅限 2 的整数次幂) - 小整数幂(如平方、立方)直接写
x * x或x * x * x,比Math.pow(x, 2)快且精确 - 真要用
Math.pow()时,对结果四舍五入再转整型:(int) Math.round(Math.pow(10, 2)) - 底数为负、指数非整数时返回
NaN,比如Math.pow(-2.0, 0.5)
最常被忽略的是边界值行为——Math.abs() 对最小值无解、Math.random() 的区间开闭、Math.pow() 的浮点误差,这些都不是 bug,而是设计如此。写的时候多看一眼 Javadoc 里那句 “returns the ...” 开头的定义,比查 Stack Overflow 更快。








