Removing lowest order bit - java

Given a binary number, what is the fastest way of removing the lowest order bit?
01001001010 -> 01001001000
It would be used in code to iterate over the bits of a variable. Pseudo-code follows.
while(bits != 0){
index = getIndexOfLowestOrderBit(bits);
doSomething(index);
removeLowestOrderBit(bits);
}
The possible languages I'm considering using are C and Java.

This is what I've got so far, I'm wondering if anyone can beat this.
bits &= bits-1

Uh ... In your example, you already know the bit's index. Then it's easy:
bits &= ~(1 << index);
This will mask off the bit whose index is index, regardless of its position in the value (highest, lowest, or in-between). Come to think of it, you can of course use the fact that you know the bit is already set, and use an XOR to knock it clear again:
bits ^= (1 << index);
That saves the inversion, which is probably one machine instruction.
If you instead want to mask off the lowest set bit, without knowing its index, the trick is:
bits &= (bits - 1);
See here for instance.

You can find the lowest set bit using x & (~x + 1). Example:
x: 01101100
~x+1: 10010100
--------
00000100
Clearing the lowest set bit then becomes x & ~(x & (~x + 1)):
x: 01101100
~(x&(~x+1)): 11111011
--------
01101000
Or x & (x - 1) works just as well and is easier to read.

The ever-useful Bit Twiddling Hacks has some algorithms for counting zero bits - that will help you implement your getIndexOfLowestOrderBit function.
Once you know the position of the required bit, flipping it to zero is pretty straightforward, e.g. given a bit position, create mask and invert it, then AND this mask against the original value
result = original & ~(1 << pos);

You don't want to remove the lowest order bit. You want to ZERO the lowest order SET bit.
Once you know the index, you just do 2^index and an exclusive or.

In Java use Integer.lowestOneBit().

I don't know if this is comparable fast, but I think it works:
int data = 0x44A;
int temp;
int mask;
if(data != 0) { // if not there is no bit set
temp = data;
mask = 1;
while((temp&1) == 0) {
mask <<= 1;
temp >>= 1;
}
mask = ~mask;
data &= mask;
}

Related

Getting 16 least and most significant bits of an arbitrary length binary number

So the problem I am having is obtaining the least significant and most significant 16 bits of a number over 16 bits but not necessarily of any certain length.
If the number was an int which is 32 bits I believe I could just do something like:
int Num=0xFFFFFFFF
short most = (short)(Num & 0xFFFF0000);
short least =(short)(Num & 0x0000FFFF);
Result:
most=0xFFFF
least=0xFFFF
Which in theory should get me a short 16 bit number with the least and most significant bits. But the problem is I need to be able to do this for an arbitrary amount of bits number, so this approach will not work because it will change what I need to & the number with. Is there a better approach to getting these values?
It seems Like there would be a fairly simple way to do this, but I can't find anything online.
Thanks
Before the main subject. your code have wrong to get most.
you should shift right for 4.
short most = (short)((Num & 0xFFFF0000) >> 0x10);
I guess you want this approach.
// lenMost should be in 0 to 32
int[] divide(int target, int lenMost) {
int MASK = 0xFFFFFFFF;
int lenLeast = 32 - lenMost;
int ret[] = new int[2]();
// get most
ret[0] = target & (MASK << lenLeast)
ret[0] >>= lenLeast;
// get least
ret[1] = target & (MASK >> lenMost);
return ret;
}

Translating this java implementation of Sieve of Eratosthenes?

This is a program in Java which implements the Sieve or Eratosthenes by storing the array of booleans as an array of bits. I have never coded in Java before, but the general idea is easy to understand. However, I cannot understand how the getBit and setBit functions work? I am guessing that the getBit function creates a bitmask with the bit i set to 1 and does bitwise AND between the mask and the array? However, I'm not really understanding the details (eg. why i is right shifted by 4 before being passed as index to array, and why MEMORY_SIZE is equal to MAX right shifted by 4). Please explain the each step of getBit and setBit in words, and if possible an equivalent implementation in Python?
private static final long MAX = 1000000000L;
private static final long SQRT_MAX = (long) Math.sqrt(MAX) + 1;
private static final int MEMORY_SIZE = (int) (MAX >> 4);
private static byte[] array = new byte[MEMORY_SIZE];
//--//
for (long i = 3; i < SQRT_MAX; i += 2) {
if (!getBit(i)) {
long j = (i * i);
while (j < MAX) {
setBit(j);
j += (2 * i);
}
}
}
//--//
public static boolean getBit(long i) {
byte block = array[(int) (i >> 4)];
byte mask = (byte) (1 << ((i >> 1) & 7));
return ((block & mask) != 0);
}
public static void setBit(long i) {
int index = (int) (i >> 4);
byte block = array[index];
byte mask = (byte) (1 << ((i >> 1) & 7));
array[index] = (byte) (block | mask);
}
Some notes in advance:
(i >> 4) divides i by 16, which is the index of the block (of 8 bits) in array that contains the i-th bit
(i >> 1) divides i by 2
7 in binary code is 111
((i >> 1) & 7) means "the three rightmost bits of i / 2", which is a number between 0 and 7 (inclusive)
(1 << ((i >> 1) & 7)) is a bit shifted to the left between 0 and 7 times (00000001, 00000010, ..., 10000000). This is the bit mask to set/get the bit of interest from the selected block.
getBit(i) explained
First line selects the 8-bit-block (i.e. a byte) in which the bit of interest is located.
Second line calculates a bit mask with exactly one bit set. The position of the set bit is the same as the one of the bit of interest within the 8-bit-block.
Third line extracts the bit of interest using an bitwise AND, returning true if this bit is 1.
setBit(i) explained
Calculation of the 8-bit-block and the bit mask is equivalent to getBit
The difference is that a bitwise OR is used to set the bit of interest.
Edit
To your first question:
It almost makes sense now, can you please explain why we are able to find the position of the bit cooresponding to the number i by shifting a bit left ((i >> 1) & 7) times? In other words, i understand what the operation is doing, but why does this give us the correct bit position?
I think this is because of the optimized nature of the algorithm. Since i is incremented in steps of 2, it is sufficient to use half of the bits (since the others would be set anyway). Thus, i can be divided by 2 to calculate the number of necessary bit shifts.
Regarding your second question:
Also, just to clarify, the reason we increment j by 2*i after each call to setBit is because we only need to set the bits cooresponding to odd multiples of i, right?
Yes, because according to https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes:
Another refinement is to initially list odd numbers only, (3, 5, ..., n), and count in increments of 2p in step 3, thus marking only odd multiples of p.
Your algorithm starts with 3, increments i by 2, and counts in increments of 2*i.
I hope this helps!

How can I extract a particular bit in Java?

I need a specific bit in a byte value stored as int value. My code is as shown below.
private int getBitValue(int byteVal, int bitShift){
byteVal = byteVal << bitShift;
int bit = (int) (byteVal >>>7);
return bit;
}
It is working when I give the bitshift as 1 but when I give the bitshift as 2 and the byteVal as 67(01000011 in binary), I get the value of 'byteVal' as 268 while 'byteVal' should be 3(000011 in binary) after the first line in the method(the left shift). What am I doing wrong here?
For some reason when I try your code I don't get what you get. For your example, if you say byteVal = 0b01000011 and bitShift = 2, then this is what I get:
byteVal = 0b01000011 << 2 = 0b0100001100
bit = (int) (0b0100001100 >>> 7) = (int) (0b010) // redundant cast
returned value: 0b010 == 2
I believe what you intended to do was shift the bit you wanted to the leftmost position, and then shift it all the way to the right to get the bit. However, your code won't do that for a few reasons:
You need to shift left by (variable length - bitShift) to get the desired bit to the place you want. So in this case, what you really want is to shift byteVal left by 6 places, not 2.
int variables are 32 bits wide, not 8. (so you actually want to shift byteVal left by 30 places)
In addition, your question appears to be somewhat contradictory. You state you want a specific bit, yet your example implies you want the bitShift-th least significant bits.
An easier way of getting a specific bit might be to simply shift right as far as you need and then mask with 1: (also, you can't use return with void, but I'm assuming that was a typo)
private int getBitValue(int byteVal, int bitShift) {
byteVal = byteVal >> bitShift; // makes the bitShift-th bit the rightmost bit
// Assumes bit numbers are 0-based (i.e. original rightmost bit is the 0th bit)
return (int) (byteVal & 1) // AND the result with 1, which keeps only the rightmost bit
}
If you want the bitShift-th least significant bits, I believe something like this would work:
private int getNthLSBits(int byteVal, int numBits) {
return byteVal & ((1 << numBits) - 1);
// ((1 << numBits) - 1) gives you numBits ones
// i.e. if numBits = 3, (1 << numBits) - 1 == 0b111
// AND that with byteVal to get the numBits-th least significant bits
}
I'm curious why the answer should be 3 and I think we need more information on what the function should do.
Assuming you want the value of the byteVal's lowest bitShift bits, I'd do the following.
private int getBitValue(int byteVal, int bitShift){
int mask = 1 << bitShift; // mask = 1000.... (number of 0's = bitShift)
mask--; // mask = 000011111 (number of 1's = bitShift)
return (byteVal & mask);
}
At the very least, this function will return 1 for getBitValue(67, 1) and 3 for getBitValue(67,2).

Odd result when bit shifting in Java

I'm trying to isolate two bytes that are next to each other add them, but there seems to be an extra bit that sometimes shows up and I can't figure out how to get rid of it. It's throwing off the answer.
The code is:
(acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L);
and I'm getting results such as
0x0000000147000000
when it should be
0x0000000047000000
How can I get rid of the 1?
Edit: acc is a long. I'm try to add the 5th and 6th byte and then that value will go into a new long in the 5th byte position.
You need to mask the bits you want at the end, because the addition may carry a bit:
((acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L)) & 0x00000000ff000000L;
I think this might be clearer if you broke it down a little:
acc&=0x00000000FFFF000000L; // isolate bytes 5 and 4
acc+=(acc<<8); // add the two bytes (we'll strip bytes 6 & 4 next)
acc&=0x00000000FF00000000L; // reduce to byte 5 only
which happens to be one less bitwise opperation too.
If I understand correctly, you want to get the value of the 5th and 6th byte, add them together, and store them in a new long that contains just that sum in the 5th byte. This would be done like this:
long 5thByte = acc & 0xff00000000 >>> 32;
long 6thByte = acc & 0xff0000000000 >>> 40;
long sum = 5thByte + 6thByte;
long longWithNewByte = sum << 32;
This will of course carryover to the 6th byte if the sum is higher than 255. To get rid of that carryover, you can use another mask.
long longWithNewByte &= 0xff00000000;

How to get the value of a bit at a certain position from a byte?

If I have a byte, how would the method look to retrieve a bit at a certain position?
Here is what I have know, and I don't think it works.
public byte getBit(int position) {
return (byte) (ID >> (position - 1));
}
where ID is the name of the byte I am retrieving information from.
public byte getBit(int position)
{
return (ID >> position) & 1;
}
Right shifting ID by position will make bit #position be in the furthest spot to the right in the number. Combining that with the bitwise AND & with 1 will tell you if the bit is set.
position = 2
ID = 5 = 0000 0101 (in binary)
ID >> position = 0000 0001
0000 0001 & 0000 0001( 1 in binary ) = 1, because the furthest right bit is set.
You want to make a bit mask and do bitwise and. That will end up looking very close to what you have -- use shift to set the appropriate bit, use & to do a bitwise op.
So
return ((byte)ID) & (0x01 << pos) ;
where pos has to range between 0 and 7. If you have the least significant bit as "bit 1" then you need your -1 but I'd recommend against it -- that kind of change of position is always a source of errors for me.
to get the nth bit in integer
return ((num >> (n-1)) & 1);
In Java the following works fine:
if (value << ~x < 0) {
// xth bit set
} else {
// xth bit not set
}
value and x can be int or long (and don't need to be the same).
Word of caution for non-Java programmers: the preceding expression works in Java because in that language the bit shift operators apply only to the 5 (or 6, in case of long) lowest bits of the right hand side operand. This implicitly translates the expression to value << (~x & 31) (or value << (~x & 63) if value is long).
Javascript: it also works in javascript (like java, only the lowest 5 bits of shift count are applied). In javascript any number is 32-bit.
Particularly in C, negative shift count invokes undefined behavior, so this test won't necessarily work (though it may, depending on your particular combination of compiler/processor).

Categories

Resources