Unset the rightmost set bit [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How do you set, clear and toggle a single bit in C?
Removing lowest order bit
n is a positive integer. How can its rightmost set bit be unset?
Say n= 7 => n = 0111.
I want 0110 as the output. Is there any simple bitwise hack to achieve the goal?

Try n & (n-1) where & is bitwise AND
n = 7
n - 1 =6
n & (n-1)=> 0 1 1 1 (7)
& 0 1 1 0 (6)
---------
0 1 1 0 (done!)
EDIT (in response to the comment given by Forest)
n = 6
n - 1 = 5
n & (n-1)=> 0 1 1 0 (6)
& 0 1 0 1 (5)
---------
0 1 0 0 (done!)

Your question is unclear.
If you just want to unset bit 0, here are some methods (with slight variations in behavior depending on your types involved):
x &= -2;
x &= ~1;
x -= (x&1);
If you want to unset the lowest bit among the bits that are set, here are some ways:
x &= x-1;
x -= (x&-x);
Note that x&-x is equal to the lowest bit of x, at least when x is unsigned or twos complement. If you want to do any bit arithmetic like this, you should use only unsigned types, since signed types have implementation-defined behavior under bitwise operations.

unsigned int clr_rm_set_bit(unsigned int n)
{
unsigned int mask = 1;
while(n & mask) {
mask <<= 1;
}
return n & ~mask;
}

Related

XOR programming puzzle advice

Given a long int x, count the number of values of a that satisfy the following conditions:
a XOR x > x
0 < a < x
where a and x are long integers and XOR is the bitwise XOR operator
How would you go about completing this problem?
I should also mentioned that the input x can be as large as 10^10
I have managed to get a brute force solution by iterating over 0 to x checking the conditions and incrementing a count value.. however this is not an optimal solution...
This is the brute force that I tried. It works but is extremely slow for large values of x.
for(int i =0; i < x; i++)
{
if((0 < i && i < x) && (i ^ x) > x)
count++;
}
long long NumberOfA(long long x)
{
long long t = x <<1;
while(t^(t&-t)) t ^= (t&-t);
return t-++x;
}
long long x = 10000000000;
printf("%lld ==> %lld\n", 10LL, NumberOfA(10LL) );
printf("%lld ==> %lld\n", x, NumberOfA(x) );
Output
10 ==> 5
10000000000 ==> 7179869183
Link to IDEOne Code
Trying to explain the logic (using example 10, or 1010b)
Shift x to the left 1. (Value 20 or 10100b)
Turn off all low bits, leaving just the high bit (Value 16 or 10000b)
Subtract x+1 (16 - 11 == 5)
Attempting to explain
(although its not easy)
Your rule is that a ^ x must be bigger than x, but that you cannot add extra bits to a or x.
(If you start with a 4-bit value, you can only use 4-bits)
The biggest possible value for a number in N-bits is 2^n -1.
(eg. 4-bit number, 2^4-1 == 15)
Lets call this number B.
Between your value x and B (inclusive), there are B-x possible values.
(back to my example, 10. Between 15 and 10, there are 5 possible values: 11, 12, 13, 14, 15)
In my code, t is x << 1, then with all the low bits turned off.
(10 << 1 is 20; turn off all the low bits to get 16)
Then 16 - 1 is B, and B - x is your answer:
(t - 1 - x, is the same as t - ++x, is the answer)
One way to look at this is to consider each bit in x.
If it's 1, then flipping it will yield a smaller number.
If it's 0, then flipping it will yield a larger number, and we should count it - and also all the combinations of bits to the right. That conveniently adds up to the mask value.
long f(long const x)
{
// only positive x can have non-zero result
if (x <= 0) return 0;
long count = 0;
// Iterate from LSB to MSB
for (long mask = 1; mask < x; mask <<= 1)
count += x & mask
? 0
: mask;
return count;
}
We might suspect a pattern here - it looks like we're just copying x and flipping its bits.
Let's confirm, using a minimal test program:
#include <cstdlib>
#include <iostream>
int main(int, char **argv)
{
while (*++argv)
std::cout << *argv << " -> " << f(std::atol(*argv)) << std::endl;
}
0 -> 0
1 -> 0
2 -> 1
3 -> 0
4 -> 3
5 -> 2
6 -> 1
7 -> 0
8 -> 7
9 -> 6
10 -> 5
11 -> 4
12 -> 3
13 -> 2
14 -> 1
15 -> 0
So all we have to do is 'smear' the value so that all the zero bits after the most-significant 1 are set, then xor with that:
long f(long const x)
{
if (x <= 0) return 0;
long mask = x;
while (mask & (mask+1))
mask |= mask+1;
return mask ^ x;
}
This is much faster, and still O(log n).

Adding n bits to the first n bits of another number

I am doing a project on digital filters. I needed to know how to add a 4 bit binary number to the most significant 4 bits of an 8 bit number. For example:
0 1 0 0 0 0 0 0 //x
+ 1 0 1 0 //y
= 1 1 1 0 0 0 0 0 //z
Can I add using a code somewhat like this?
z=[7:4]x + y
or should I have to concatenate the 4 bit number with another four zeros and add?
Assuming y is the 4 bit number and x the 8 bit number:
If you do
assign z = x[7:4] + y
Then you are doing a 4-bit addition and the most significant part of z is padded with 0's.
If you do
assign z = y[7:4] + x
You will get an error message from the synthesizer, as subscripts for y are wrong.
So do as this:
assign z = {y,4'b0} + x
Which performs an 8-bit addition with x and the value of y shifted 4 bits to the left, which is want you wanted.

Why does "number & (~(1 << 3))" not work for 0's?

I'm writing a program that exchanges the values of the bits on positions 3, 4 and 5 with bits on positions 24, 25 and 26 of a given 32-bit unsigned integer.
So lets say I use the number 15 and I want to turn the 4th bit into a 0, I'd use...
int number = 15
int newnumber = number & (~(1 << 3));
// output is 7
This makes sense because I'm exchanging the 4th bit from 1 to 0 so 15(1111) becomes 7(0111).
However this wont work the other way round (change a 0 to a 1), Now I know how to achieve exchanging a 0 to a 1 via a different method, but I really want to understand the code in this method.
So why wont it work?
The truth table for x AND y is:
x y Output
-----------
0 0 0
0 1 0
1 0 0
1 1 1
In other words, the output/result will only be 1 if both inputs are 1, which means that you cannot change a bit from 0 to 1 through a bitwise AND. Use a bitwise OR for that (e.g. int newnumber = number | (1 << 3);)
To summarize:
Use & ~(1 << n) to clear bit n.
Use | (1 << n) to set bit n.
To set the fourth bit to 0, you AND it with ~(1 << 3) which is the negation of 1000, or 0111.
By the same reasoning, you can set it to 1 by ORing with 1000.
To toggle it, XOR with 1000.

How does condition statement work with bit-wise operators?

I tried to understand how if condition work with bitwise operators.
A way to check if a number is even or odd can be done by:
#include <iostream>
#include <string>
using namespace std;
string test()
{
int i = 8; //a number
if(i & 1)
return "odd";
else
return "even";
}
int main ()
{
cout << test();
return 0;
}
The Part I don't understand is how the if condition work. In this case if i = 8 then the in If statement it is doing 1000 & 1 which should gives back 1000 which equal 8.
If i = 7, then in if statement it should be doing 111 & 1 which gives back 111 which equal 7
Why is it the case that if(8) will return "even" and if(7) return "odd"? I guess I want to understand what the if statement is checking to be True and what to be False when dealing with bit-wise operators.
Just A thought when I wrote this question down is it because it's actually doing
for 8: 1000 & 0001 which gives 0
for 7: 0111 & 0001 which gives 1?
Yes, you are right in the last part. Binary & and | are performed bit by bit. Since
1 & 1 == 1
1 & 0 == 0
0 & 1 == 0
0 & 0 == 0
we can see that:
8 & 1 == 1000 & 0001 == 0000
and
7 & 1 == 0111 & 0001 == 0001
Your test function does correctly compute whether a number is even or odd though, because a & 1 tests whether there is a 1 in the 1s place, which there only is for odd numbers.
Actually, in C, C++ and other major programming languages the & operator do AND operations in each bit for integral types. The nth bit in a bitwise AND is equal to 1 if and only if the nth bit of both operands are equal to 1.
For example:
8 & 1 =
1000 - 8
0001 - 1
----
0000 - 0
7 & 1 =
0111 - 7
0001 - 1
----
0001 - 1
7 & 5 =
0111 - 7
0101 - 5
----
0101 - 5
For this reason doing a bitwise AND between an even number and 1 will always be equal 0 because only odd numbers have their least significant bit equal to 1.
if(x) in C++ converts x to boolean. An integer is considered true iff it is nonzero.
Thus, all if(i & 1) is doing is checking to see if the least-significant bit is set in i. If it is set, i&1 will be nonzero; if it is not set, i&1 will be zero.
The least significant bit is set in an integer iff that integer is odd, so thus i&1 is nonzero iff i is odd.
What you say the code is doing is actually how bit-wise operators are supposed to work. In your example of (8 & 1):
1000 & 0001 = 0000
because in the first value, the last bit is set to 0, while in the second value, the last bit is set to 1. 0 & 1 = 0.
0111 & 0001 = 0001
In both values, the last bit is set to 1, so the result is 1 since 1 & 1 = 1.
The expression i & 1, where i is an int, has type int. Its value is 1 or 0, depending on the value of the low bit of i. In the statement if(i & 1), the result of that expression is converted to bool, following the usual rule for integer types: 0 becomes false and non-zero becomes true.

Mix of two bit sequences

Is there any clever way to mix two bit sequences in such way that bits from first sequence will be on odd places, and bits from second sequence will be on even places.
Both sequences are no longer than 16b so output will fit into 32bit integer.
Example:
First sequence : 1 0 0 1 0 0
Second sequence : 1 1 1 0 1 1
Output : 1 1 0 1 0 1 1 0 0 1 0 1
I thought about making integer array of size 2^16 and then the output would be:
arr[first] << 1 | arr[second]
Have a look at http://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableLookup This page lists the obvious (for loop) and 3 optimized algorithms. Neither one is particularly simple but without testing I'd guess they are considerably faster than a loop.
in C#:
public Int32 Mix(Int16 b1, Int16 b2)
{
Int32 res = 0;
for (int i=0; i<16; i++)
{
res |= ((b2 >> i) & 1) << 2*i;
res |= ((b1 >> i) & 1) << 2*i + 1;
}
return res;
}