Java整数除法向零截断而非向下取整;异号时结果与floor不同,需用Math.floorDiv()或手动实现;余数应配Math.floorMod()保证非负。

Java 中整数除法(/)对正数和负数都直接截断小数部分,即向零取整(truncation),**不是向下取整(floor)**。这点常被误解,需特别注意。
整数除法的真实行为:向零截断
Java 的 int / int 或 long / long 运算结果是商的整数部分,小数全部丢弃,方向始终朝零靠近:
-
7 / 3→ 2(0.666… → 截断为 2,等价于向下取整) -
-7 / 3→ -2(-2.333… → 截断为 -2,但向下取整应为 -3) -
7 / -3→ -2(同上,向零) -
-7 / -3→ 2
可见:仅当被除数与除数同号且整除时,结果才等价于向下取整;异号时,向零截断 ≠ 向下取整。
需要真正向下取整时怎么办?
若业务逻辑要求数学意义上的 floor 除法(如分页计算、数组分块索引),不能直接用 /,可借助 Math.floorDiv()(Java 8+):
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
Math.floorDiv(-7, 3)→ -3(正确向下取整) -
Math.floorDiv(7, -3)→ -3 -
Math.floorDiv(-7, -3)→ 2
它对所有符号组合都返回 floor(a/b),且不抛异常(与普通除法一样,/0 仍会抛 ArithmeticException)。
手动实现 floor 除法(兼容旧版本)
若无法使用 Java 8+,可用以下逻辑模拟:
public static int floorDiv(int x, int y) {
int r = x / y;
// 只有异号且不能整除时,需要减 1
if (r * y != x && (x < 0) ^ (y < 0)) {
r--;
}
return r;
}原理:先做普通除法,再检查是否“被截掉的部分为负”,若是(即异号且有余数),就减 1 补回 floor 效果。
余数也要同步处理:用 Math.floorMod()
普通 % 运算符满足:(a / b) * b + (a % b) == a,但它也是向零定义的余数(可正可负)。而 floor 除法应配 floor 余数,满足:floorDiv(a,b) * b + floorMod(a,b) == a,且 0 ≤ floorMod(a,b) < |b|。
-
-7 % 3→ -1(普通余数) -
Math.floorMod(-7, 3)→ 2(非负余数,符合模运算直觉)
分页、哈希桶分配等场景中,用 floorMod 能避免负索引问题。

















