Integer.remainderUnsigned(int, int) 是 JDK 8 引入的静态方法,用于对两个 int 执行无符号除法取余,将操作数视为 0 到 2³²−1 的无符号值,结果非负;如 Integer.remainderUnsigned(-5, 3) 返回 1。

Java 中没有 Integer.remainderUnsigned() 方法 —— 这是一个常见误解。Java 标准库(截至 JDK 21)**并未提供名为 Integer.remainderUnsigned() 的静态方法**。你可能混淆了 Integer.remainderUnsigned(int, int) 的实际存在形式,或误记了类似方法名。
实际可用的无符号取模方法是 Integer.remainderUnsigned(int dividend, int divisor)
该方法自 JDK 8 起引入,是 Integer 类的静态工具方法,用于对两个 int 值执行**无符号除法的余数运算**(即把 int 当作 32 位无符号整数看待)。
关键点:
- 它接受两个
int参数,但语义上将它们解释为无符号值(0 到 2³²−1); - 结果也是
int类型,且始终为非负数(符合无符号模运算定义); - 当除数为 0 时抛出
ArithmeticException(与有符号除法一致); - 它不修改变量本身,也不“对待符号变量”做隐式转换——你需要显式传入值。
为什么需要它?有符号 % 和无符号模的区别
Java 的 % 运算符是有符号的:结果符号与被除数相同。例如:
System.out.println(-5 % 3); // 输出 -2(有符号余数) System.out.println(Integer.remainderUnsigned(-5, 3)); // 输出 1(无符号余数:(2³²−5) % 3 = 4294967291 % 3 = 1)
这是因为 -5 作为无符号解释是 0xFFFFFFFB = 4294967291,再对 3 取模得 1。
典型适用场景:
- 网络协议解析(如 IPv4 地址、校验和计算);
- 哈希算法中需统一用无符号算术;
- 与 C/C++ 代码交互,对方使用
uint32_t进行模运算。
正确使用方式:传入原始 int 值,无需“转换变量类型”
Java 中 int 始终是有符号的,但 remainderUnsigned 仅改变**运算解释方式**,不改变存储。你只需直接传参:
int a = -1; // 逻辑上想当作 4294967295 int b = 10; int result = Integer.remainderUnsigned(a, b); // 返回 5(因为 4294967295 % 10 == 5)
注意:
- 不要尝试先转成
long再右移或掩码——这容易出错且不必要; - 若操作数来自
byte/short,需先用& 0xFF或& 0xFFFF零扩展为正的int,再调用该方法; - 对
long类型,应使用Long.remainderUnsigned(long, long)(JDK 8+)。
替代方案(仅在旧 JDK 中需要)
若受限于 JDK
public static int remainderUnsigned(int dividend, int divisor) {
if (divisor == 0) throw new ArithmeticException("divide by zero");
long ud = dividend & 0x00000000FFFFFFFFL;
long ud2 = divisor & 0x00000000FFFFFFFFL;
return (int) (ud % ud2);
}
原理:将 int 零扩展为 long,利用 long 的有符号模运算等价于 32 位无符号模(因 long 足够宽),再截断回 int。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











