Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java get bit ranges from a long

I need to extract certain bit ranges from with a long value, for example:

long input = 15367 (11110000000111)

What I need to then do is to extract two long values from the original long,

First long is 5 bits starting from bit 0, so bits 0:4 = 7 (0111)
Second long is 56 bits starting from bit 8, so bits 7:55 = 60 (1111000)

I know this can be done with bit shifting and masking, however I'm not entirely sure how to implement that so it's dynamic each time, as each time I need to do this, the long will be different, and so too will the specific bit ranges.

I've been reading about BitSets and BitArrays, however I'm not entirely sure these are the right things for the job.

Any advice on the best way to implement this would be greatly appreciated.

Thanks!

like image 623
Tony Avatar asked Aug 06 '13 14:08

Tony


People also ask

How to set the bits of a given range?

range = (((1 << (l - 1)) - 1) ^ ((1 << (r)) - 1)); 2. Now, perform "n = n | range". This will set the bits in the range from l to r in n.

How many bits is an int Java?

int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1.


2 Answers

To extract nrBits bits starting from offset offset, you can do:

public static long extractSub(final long l, final int nrBits, final int offset)
{
    final long rightShifted = l >>> offset;
    final long mask = (1L << nrBits) - 1L;
    return rightShifted & mask;
}

Note the user of the >>> right shift operator; this is so you don't carry the sign bit around.

As to (1L << nrBits) - 1L, that is 2^nrBits - 1. The L is to have long constants.

Also note that there is no "bounds checking" (for instance, an offset or number of bits greater than 63 or negative).

like image 195
fge Avatar answered Sep 19 '22 13:09

fge


To extract bits between bit x and bit y, where x is the larger of the two numbers, you could say

long mask = (Math.pow(2,x+1)-1)- (Math.pow(2,y+1)-1);
long extract = input & mask;
like image 41
user1111284 Avatar answered Sep 17 '22 13:09

user1111284