
Math.round()不是“四舍五入”,而是“加0.5后floor”
很多人以为 Math.round() 就是数学课上的四舍五入,但实际行为更机械:它对 double 参数执行 Math.floor(x + 0.5),再强制转为 long。这就解释了为什么 Math.round(-11.5) 得到的是 -11 而不是 -12——因为 -11.5 + 0.5 = -11.0,Math.floor(-11.0) 还是 -11.0。
- 正数时表现接近四舍五入:
Math.round(2.5) → 3,Math.round(2.4) → 2 - 负数时“.5”不进位:
Math.round(-2.5) → -2(不是 -3) - 返回类型是
long(double输入)或int(float输入),不能直接赋给int变量而不强转 - 如果真要“对称四舍五入”(-2.5 → -3),得自己写逻辑,比如用
BigDecimal的HALF_UP模式
Math.ceil()和Math.floor()的方向感必须看符号
Math.ceil() 是“向上取整”,意思是“找 ≥ 当前值的最小整数”;Math.floor() 是“向下取整”,即“找 ≤ 当前值的最大整数”。这个“上/下”是数轴方向,不是人眼直觉的“往上加”或“往下减”。
- 对正数:
Math.ceil(3.2) → 4.0,Math.floor(3.2) → 3.0(符合直觉) - 对负数:
Math.ceil(-3.2) → -3.0(-3 > -3.2,所以是“向上”),而Math.floor(-3.2) → -4.0(-4 - 两者返回值类型都是
double,哪怕输入是整数,如Math.ceil(5.0)仍返回5.0,不是5 - 别指望它们处理
null或非数字——传NaN会返回NaN,传Infinity返回原值,不抛异常
什么时候该用哪个?看业务语义,不是看数字大小
选函数的关键不是“哪个结果看起来更整”,而是你真正想表达的业务含义:
- 分页计算总页数(比如每页10条,共23条)→ 用
Math.ceil((double) total / pageSize),因为哪怕剩1条也要开一页 - 计算能完整装下的箱数(每箱装8件,有30件)→ 同样用
Math.ceil(),30 ÷ 8 = 3.75 → 需4箱 - 截断小数保留整数部分(比如年龄、楼层号)→ 用
Math.floor(),Math.floor(2.9) → 2.0,Math.floor(-2.9) → -3.0 - 做统计四舍五入展示(如平均分保留一位小数)→ 别直接用
Math.round()原始值,先乘10、round、再除10;或者用BigDecimal避免浮点误差
常见坑:类型混淆 + 负零 + 浮点精度
这三个函数表面简单,但组合使用时容易掉进类型和精度陷阱:
立即学习“Java免费学习笔记(深入)”;
-
Math.round()对float返回int,对double返回long,混用时可能隐式溢出(比如Math.round(1e10)是long,但若误接int变量会截断) -
Math.ceil(-0.0)返回-0.0(不是0.0),虽然数值相等,但Double.doubleToLongBits()不同,单元测试里可能踩雷 - 浮点数本身不精确,
Math.round(2.675)实际可能不是2.675,而是略小一点的值(如2.6749999999999998),导致 round 成2而不是预期的3 - 如果涉及金额、计费、科学计算,一律避免用这三个函数做核心逻辑——改用
BigDecimal显式指定舍入模式
最常被忽略的一点:这些函数都只是“取整工具”,它们不解决语义问题。比如“向上取整”在负数场景是否真的符合你的业务规则,得靠人判断,而不是靠函数名里的“ceil”二字自动保证。










