I want to write a function that takes an int between 1 and 64, and returns an appropriate "bitmask", with as many 1 bits as the input.
I started like this:
/** Computes a bitmaks */
private static long mask(final int bitsPerValue) {
return (1L << bitsPerValue) - 1L;
}
But realized that it gives the wrong value for 64:
(1L << 64) - 1L == 1L - 1L == 0
Now I have this:
/** Computes a bitmaks */
private static long mask(final int bitsPerValue) {
return (bitsPerValue == 64) ? -1 : ((1L << bitsPerValue) - 1L);
}
It's rather ugly. And conditionals can change the control flow, so they are more expensive than simple arithmetic operations. I could just pre-compute the masks and put them in a static array, but array access is also more expensive than simple arithmetic operations, probably even more expensive than the conditional.
Is there a reasonable way of writing this without a conditional? This code is going to run zillions of time per second, so it has to be fast.
Bitmasking allows us to store multiple values inside one numerical variable. Instead of thinking about this variable as a whole number, we treat its every bit as a separate value. Because a bit can equal either zero or one, we can also think of it as either false or true.
In computer science, a mask or bitmask is data that is used for bitwise operations, particularly in a bit field. Using a mask, multiple bits in a byte, nibble, word, etc. can be set either on or off, or inverted from on to off (or vice versa) in a single bitwise operation.
Bit masks are used to access specific bits in a byte of data. This is often useful as a method of iteration, for example when sending a byte of data serially out a single pin. In this example the pin needs to change its state from high to low for each bit in the byte to be transmitted.
Bit masking is simply the process of storing data truly as bits, as opposed to storing it as chars/ints/floats. It is incredibly useful for storing certain types of data compactly and efficiently. The idea for bit masking is based on boolean logic.
Here is a way to do it without conditionals:
private static long mask(final int bitsPerValue) {
return ((1L << bitsPerValue) - (bitsPerValue >> 6)) - 1L;
}
In Java, 1L << bitsPerValue
only uses the six lowest-order bits of bitsPerValue
, which means that calling your original function with bitsPerValue=64
is the same as calling it with bitsPerValue=0
. The version I present above takes care of that: when bitsPerValue=64
, the expression reduces to
(1L - 1L) - 1L == -1L
Now, if you're really going to be calling this "zillions of times per second", I think the best strategy is to benchmark all variants of the code, including the one with conditionals and the one with the lookup table.
I tried:
long value = 0xffffffffffffffffl >>> (64 - i); // that's ef ef ef... el.
but this seems to give a problem with i = 0. My gripe with Java not having unsigned ints again. The above works in c. Maybe the above will work in Java 7, given that 'value' is unsigned.
However, since you don't need zero, the above will work fine for you, i.e. values 1 to 64.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With