这可能不是一个完美的答案,因为我不太确定 Java 在调用 Integer.compareUnsigned(-1, 2) 时究竟做了什么,但我会尝试解释我认为正在发生的事情。
首先我要指出的是
Integer.compareUnsigned(-1, 2)
返回 1,表示 -1 大于 2。为什么我会在这里解释。
Integer.compare(int, int)
就像手动进行一般的整数比较。
在解释 Integer.compareUnsigned(int, int) 之前,让我们先看看有符号整数和无符号整数是什么。
Java 使用 32 位来存储整数。这意味着int 变量最多可以表示 2^32 个数字。值的范围取决于所使用的整数表示。
对于无符号整数,这将是 0 到 4,294,967,295 (2^32 − 1)。这意味着 32 位系统上的最小无符号整数是 0,而 32 位系统上的最大无符号整数是 4,294,967,295。
对于有符号整数将是 -2,147,483,648 (-2^31) 到 2,147,483,647 (2^31 - 1) 以表示为二进制补码。
现在您看到 -1 在无符号表示中不存在。在像 C 这样具有无符号类型的语言中。当你做 unsigned int x = -1;在我的 64 位基于 Intel 的 Mac 上(我在这里比较具体,因为与 Java 不同,C 有点特定于实现),-1 被转换为 4294967295,它是无符号整数的最大值。 -2 转换为 4294967294,仅比无符号整数的最大值小 1。
#include <stdio.h>
int main() {
unsigned int x = -1;
unsigned int y = -2;
printf("x = %u\ny = %u\n", x, y);
return 0;
}
输出
x = 4294967295
y = 4294967294
现在您看到在 C 中将负数转换为带符号的等价物。我不太确定这是如何完成的,但您可以查看这个答案以进一步了解它https://stackoverflow.com/a/7152835/4801462
因此,当您调用 Integer.compareUnsigned(-1, 2) 时,我的猜测是 Java 试图将 -1 视为无符号整数。这意味着 -1 将在比较完成之前转换为非负值。这是如何完成的我不太确定,因为文档没有说,但你不应该指望这一点。为什么这么说?
Java 确实 NOT 具有无符号类型,并且 Java 中的 int 能够保持正的最大值 2,147,483,647 (2^31 − 1),大约是一半unsigned int 的最大值。因此,即使 -1 被视为无符号整数,它也可能会溢出 int 变量,这将导致 -1 的无符号版本以外的内容存储在该变量中。
我的建议是,除非你 100% 做好自己的工作,否则不要使用这种方法。
注意
更有经验的人可能会有更好的答案。我从来没有使用过这种方法。我只是应用了 4 年前从大学学到的知识来回答这个问题。
参考文献:
https://en.wikipedia.org/wiki/32-bit
编辑
当您在 Integer.compareUnsigned(int, int) 中发送 -1 时,Java 可以做的是获取 -1 的无符号等效项并将其存储在 long 中,因为它可能会溢出 int 然后执行比较。