Reputation: 9223
I have a method to extract the most significant, non-zero byte in an integer using the following method:
private static int getFirstByte(int n)
{
while (n > 0xFF)
n >>= 8;
return n;
}
There's a logic problem with this method. The integer parameter could be negative, which means it would return the number being passed in, which is incorrect.
There is also a possible issue with the method itself. It is using a while loop.
Is there a way to perform this logic without a while loop and also possibly avoiding the incorrectly returned result for negative numbers?
Upvotes: 2
Views: 1885
Reputation: 121669
Not clever, not elegant - but I believe it does "extract the most significant, non-zero byte in an integer ... without using a loop":
private static int getFirstByte(int n) {
int i;
if ((i = n & 0xff000000) != 0)
return (i >> 24) & 0xff;
if ((i = n & 0xff0000) != 0)
return (i >> 16) & 0xff;
if ((i = n & 0xff00) != 0)
return (i >> 8) & 0xff;
// all of the higher bytes are zeroes
return n;
}
Upvotes: 3
Reputation: 5488
I assume by get the first non-zero byte
in an int
you mean natural 8 bit breaks of the int
and not a dynamic 8 bit break.
Natural 8 bit breaks:
00000000
|
00010110
|
10110010
|
11110001
==> 00010110
Dynamic 8 bit break:
00000000000
|
10110101
|
1001011110001
==> 10110101
This will return the first non-zero byte
on a natural 8-bit break of an int
without looping or branching. This code may or may not be more efficient then paulsm4
's answer. Be sure to do benchmarking and/or profiling of the code to determine which is best for you.
Java Code: ideone link
class Main {
public static void main(String[] args) {
int i,j;
for (i=0,j=1; i<32; ++i,j<<=1) {
System.out.printf("0x%08x : 0x%02x\n",j,getByte(j));
}
}
public static byte getByte(int n) {
int x = n;
x |= (x >>> 1);
x |= (x >>> 2);
x |= (x >>> 4);
x |= (x >>> 8);
x |= (x >>> 16);
x -= ((x >>> 1) & 0x55555555);
x = (((x >>> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >>> 4) + x) & 0x0f0f0f0f);
x += (x >>> 8);
x += (x >>> 16);
x &= 0x0000003f;
x = 32 - x; // x now equals the number of leading zeros
x &= 0x00000038; // mask out last 3 bits (cause natural byte break)
return (byte)((n&(0xFF000000>>>x))>>>(24-x));
}
}
Upvotes: 2
Reputation: 18960
You could use log n / log 256
… But then you’d have a bigger problem.
Upvotes: 2