You can perform unsigned comparisons of longs without using horribly inefficient BigIntegers. 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 263 – 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 263 – 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 263:
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 263 + 1 to 264 – 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 264 – 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 264 – 1:
boolean aLT2to64minus1 = (a != -1L); boolean aLE2to64minus1 = true; boolean aEQ2to64minus1 = (a == -1L); boolean aNE2to64minus1 = (a != -1L); boolean aGE2to64minus1 = (a == -1L); boolean aGT2to64minus1 = false;
