You can perform unsigned comparisons of `long`

s without using horribly inefficient `BigInteger`

s. After testing a few ideas I came up with against some code by Tamutnefret of Freenode’s ##java, I found his code was fastest, so I’ve based the code below on it.

## Unsigned comparisons to another variable

Here are efficient ways to do all six unsigned comparisons:

boolean aLTb = (a < b) ^ (a < 0L) ^ (b < 0L); boolean aLEb = (a <= b) ^ (a < 0L) ^ (b < 0L); boolean aEQb = (a == b); boolean aNEb = (a != b); boolean aGEb = (a >= b) ^ (a < 0L) ^ (b < 0L); boolean aGTb = (a > b) ^ (a < 0L) ^ (b < 0L);

## Unsigned comparisons to constants

If you’re comparing to a constant, here are *even more* efficient ways to do it.

Comparing to zero:

boolean aLTzero = false; boolean aLEzero = (a == 0L); boolean aEQzero = (a == 0L); boolean aNEzero = (a != 0L); boolean aGEzero = true; boolean aGTzero = (a != 0L);

Comparing to one:

boolean aLTone = (a == 0L); boolean aLEone = (a <= 1L) ^ (a < 0L); boolean aEQone = (a == 1L); boolean aNEone = (a != 1L); boolean aGEone = (a != 0L); boolean aGTone = (a > 1L) ^ (a < 0L);

Comparing to anything from two to 2^{63} – 2:

boolean aLTposConst = (a <= posConstMinus1) ^ (a < 0L); boolean aLEposConst = (a <= posConst) ^ (a < 0L); boolean aEQposConst = (a == posConst); boolean aNEposConst = (a != posConst); boolean aGEposConst = (a > posConstMinus1) ^ (a < 0L); boolean aGTposConst = (a > posConst) ^ (a < 0L);

Comparing to 2^{63} – 1:

boolean aLT2to63minus1 = (a >= 0L) ^ (a == Long.MAX_VALUE); boolean aLE2to63minus1 = (a >= 0L); boolean aEQ2to63minus1 = (a == Long.MAX_VALUE); boolean aNE2to63minus1 = (a != Long.MAX_VALUE); boolean aGE2to63minus1 = (a < 0L) ^ (a == Long.MAX_VALUE); boolean aGT2to63minus1 = (a < 0L);

Comparing to 2^{63}:

boolean aLT2to63 = (a >= 0L); boolean aLE2to63 = (a >= 0L) ^ (a == Long.MIN_VALUE); boolean aEQ2to63 = (a == Long.MIN_VALUE); boolean aNE2to63 = (a != Long.MIN_VALUE); boolean aGE2to63 = (a < 0L); boolean aGT2to63 = (a < 0L) ^ (a == Long.MIN_VALUE);

Comparing to anything from 2^{63} + 1 to 2^{64} – 3 (make sure you write the constant in signed form):

boolean aLTnegConst = (a < negConst) ^ (a >= 0L); boolean aLEnegConst = (a <= negConst) ^ (a >= 0L); boolean aEQnegConst = (a == negConst); boolean aNEnegConst = (a != negConst); boolean aGEnegConst = (a >= negConst) ^ (a >= 0L); boolean aGTnegConst = (a > negConst) ^ (a >= 0L);

Comparing to 2^{64} – 2:

boolean aLT2to64minus2 = (a != -1L) && (a != -2L); boolean aLE2to64minus2 = (a != -1L); boolean aEQ2to64minus2 = (a == -2L); boolean aNE2to64minus2 = (a != -2L); boolean aGE2to64minus2 = (a == -1L) || (a == -2L); boolean aGT2to64minus2 = (a == -1L);

Comparing to 2^{64} – 1:

boolean aLT2to64minus1 = (a != -1L); boolean aLE2to64minus1 = true; boolean aEQ2to64minus1 = (a == -1L); boolean aNE2to64minus1 = (a != -1L); boolean aGE2to64minus1 = (a == -1L); boolean aGT2to64minus1 = false;

Advertisements