What is the difference between compare() and compareUnsigned() in Java

Tags:



I know compare(int a, int b) returns 1 if a > b, 0 if a == b, -1 a < b. When I faced to compareUnsigned() didn’t get how does it function. I have done some research on the documentation of this method in IntelliJ Idea about this method and found out how does
compareUnsigned() static method work after it receives integer x and y as arguments :

public static int compareUnsigned(int x, int y) {
        return compare(x + -2147483648, y + -2147483648);
    }

Could anyone explain if there is any special feature of this method compared to compare(int a, int b) method and how does it do .

Answer

This may not be a perfect answer as I’m not really sure exactly what Java does when you call Integer.compareUnsigned(-1, 2) but I will try explain what I think is happening.

First I will like to point out that

Integer.compareUnsigned(-1, 2)

returns 1 which indicates -1 is greater than 2. Why is what I’ll try to explain here.

Integer.compare(int, int)

Just does normal integer comparison as you would do manually.

Before explaining Integer.compareUnsigned(int, int) let’s look at what signed and unsigned ints are.

Java uses 32 bits to store integers. This means an int variable can represent up to 2^32 numbers. The range of values will depend on the integer representation used.

For unsigned integers this will be 0 through 4,294,967,295 (2^32 − 1). Which means the minimum unsigned integer on a 32 bit system is 0 and the maximum unsigned integer on 32 bit system is 4,294,967,295.

For signed integers will be −2,147,483,648 (−2^31) through 2,147,483,647 (2^31 − 1) for representation as two’s complement.

Now you see that -1 doesn’t exist in the unsigned representation. In languages like C that have unsigned type. When you do unsigned int x = -1; On my 64 bit Intel based Mac (I am specific here because unlike Java, C is a little bit implementation specific), -1 is converted to 4294967295 which is the largest value of a unsigned integer. -2 is converted to 4294967294 which is just one less than the largest value of an unsigned integer.

#include <stdio.h>

int main() {
    unsigned int x = -1;
    unsigned int y = -2;

    printf("x = %uny = %un", x, y);
    return 0;   
}

Output

x = 4294967295 
y = 4294967294

Now you see that negative numbers are been converted to a signed equivalent in C. How that is done I’m not really sure but you can have a look at this answer to understand it more https://stackoverflow.com/a/7152835/4801462

So when you call Integer.compareUnsigned(-1, 2), my guess is that Java tries to treat -1 as an unsigned int. Which means -1 will be converted to non negative value before the comparison is done. How that is done I’m not really sure as the documentation doesn’t say but you shouldn’t count on that. Why do I say so?

Java does NOT have an unsigned type and an int in Java is capable of holding a positive maximum value of 2,147,483,647 (2^31 − 1) which is about half the maximum value of an unsigned int. So even if -1 is to be treated as an unsigned int, it will probably overflow the int variable which will cause something other than the unsigned version of -1 to be stored in that variable.

My advice is, avoid using that method unless you are 100% what you are doing.

NB

A more experienced person will probably have a better answer. I’ve never used this method. I just applied knowledge I learned from college 4 years ago to answer this question.

References:

https://en.wikipedia.org/wiki/32-bit

EDIT

What Java could be doing when you send in -1 in Integer.compareUnsigned(int, int) is get the unsigned equivalent of -1 and store it inside a long since it might overflow an int then do the comparison.



Source: stackoverflow