英文:
Unsigned Integer Comparison
问题
我原本以为在下面的示例中,"compareUnsigned" 会返回 0。但实际上它返回的是 -1。为什么 b 被视为比 a 大呢?
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE * -1;
System.out.printf("x 相对于 y 的比较结果:%d%n", Integer.compare(a, b));
System.out.printf("x 相对于 y 的无符号比较结果:%d%n", Integer.compareUnsigned(a, b));
英文:
I was assuming that "compareUnsigned" in the below example will return 0. But it is returning -1. Why is b treated as greater than a?
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE * -1;
System.out.printf("x compared to y: %d%n", Integer.compare(a, b));
System.out.printf("x compared to y: %d%n", Integer.compareUnsigned(a, b));
答案1
得分: 4
compareUnsigned
不会做你认为它会做的事情。你可能认为它只比较参数的大小,而不考虑它们的符号。然而,它实际上的作用是将这两个整数视为uint
(在Java中实际上不存在这个类型,这就是为什么有这个方法的原因!)。
也许文档对此并不是很清楚,它只是说“将值视为无符号的”。这可能被解释为“忽略符号”,但如果你查看compareUnsigned
的实现,你会看到它实际上做了什么:
public static int compareUnsigned(int x, int y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
无论如何,要比较两个uint
,我们只需要查看它们的二进制表示。MAX_VALUE
在二进制中是31个1(让我们忽略前导零),而它的否定是1个1,后面跟着30个零,再后面是1个1。
1111111111111111111111111111111 // MAX_VALUE
10000000000000000000000000000001 // -MAX_VALUE
很明显,哪个无符号的二进制数字更大。显然是那个位数更多的数字。
<hr>
要实际比较这两个整数而不考虑符号,应用Math.abs
然后进行比较(但对于Integer.MIN_VALUE
,这种方法不适用,你需要单独检查):
Integer.compare(Math.abs(a), Math.abs(b))
英文:
compareUnsigned
does not do what you think it does. You probably thought it compares the magnitudes of the arguments only, without considering their signs. However, what it really does is that it treats the two ints as a uint
(which doesn't really exist in Java, which is why this method exists!).
Maybe the documentation isn't really clear on this, it just says "treating the values as unsigned." which could be interpreted as "ignoring the signs", but if you look at the implementation of compareUnsigned
, you'll see what it actually does:
public static int compareUnsigned(int x, int y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
Anyway, to compare two uint
s, we just have to look at their binary representation. MAX_VALUE
in binary is 31 ones (let's ignore leading zeros), whereas the negation of it is 1 one followed by 30 zeros, followed by 1 one.
1111111111111111111111111111111 // MAX_VALUE
10000000000000000000000000000001 // -MAX_VALUE
It is clear which is bigger as an unsigned binary number. It's obviously the one that has more digits.
<hr>
To actually compare the two integers without considering the signs, apply Math.abs
then compare (won't work for Integer.MIN_VALUE
though, you'd have to check that separately):
Integer.compare(Math.abs(a), Math.abs(b))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论