9

Why are the implementations of the static method compare for Long, Integer and Short in Java's library different?

For Long:

public static int compare(long x, long y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

For Integer:

public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

For Short:

public static int compare(short x, short y) {
    return x - y;
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
fluency03
  • 2,637
  • 7
  • 32
  • 62
  • 6
    Because the return type is `int` in all the cases. – Aniket Sahrawat Mar 03 '18 at 13:23
  • 2
    Because `x - y` is simpler and works for `short`. Sure, it could do it the long way, like the others, but the simpler way is also faster, so it's a **better** implementation. `x - y` will not work for `int` and `long`, so they have to do it the ternary operator way. – Andreas Mar 03 '18 at 13:24

3 Answers3

15

If you try:

System.out.println(Long.MIN_VALUE - Long.MAX_VALUE);

or

System.out.println(Integer.MIN_VALUE - Integer.MAX_VALUE);

You will get 1 because of overflow(update: should be underflow here, as mentioned in another answer), which is incorrect.

However, with

System.out.println(Short.MIN_VALUE - Short.MAX_VALUE);

you will get correct value -65535, because short will be converted to int before - operation, which prevents the overflow.

xingbin
  • 27,410
  • 9
  • 53
  • 103
4

x - y is presumably the most efficient (since the alternative involves branching twice), so that's used for short.

But x - y can't be used for int or long, because this will overflow when the resulting value doesn't fit in an int, which can give a positive value when the result should be negative, or a negative value when the result should be positive (or zero in either case).

Note: when subtracting two shorts, the resulting value is of type int, so that can never overflow.

// long - long
System.out.println((int)(2147483649l - 1l)); // -2147483648, not 2147483648
// int - int
System.out.println(-2147483648 - 1);         // 2147483647, not -2147483649
// int - int
System.out.println(1 - -2147483648);         // -2147483647, not 2147483649
// short - short
short s1 = -32768, s2 = 1;
System.out.println(s1 - s2);                 // -32769, as desired

For what it's worth: the values above were chosen since they're roughly around the minimum and maximum values for int (and short), to demonstrate at which point it overflows.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
2

int can have values between [-2147483648, +2147483647]. If you subtract -2147483648 from +2147483647, you will get 4294967295. This can't be stored in an int, therefore we use this for comparing 2 ints

return (x < y) ? -1 : ((x == y) ? 0 : 1);

The same is the case with long.

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
ncoder
  • 151
  • 1
  • 8