Unsigned comparisons in Java

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;
Advertisements
This entry was posted in Java, Optimization. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s