using "bitwise and" operator c++ - c++

I have the following code
int n = 50;
while(n) { //1
if(n & 1) cout << "1" << endl; //2
//right shift the number so n will become 0 eventually and the loop will terminate
n >>= 1; //3
}
When we use bitwise and 1 (& 1) with a number we get back the same number.
Now my question is how does c++ evaluates the following expression: n & 1.
Since:
n = 50
In binary form 50 is: 110010
If we bitwise 1 then we get: AND 1 = 110010
Now in c++ (2) the expression evaluates like this:
Instead of getting the whole sequence of bits (110010) bitwise anded with 1
it evaluates only the number of right bits we bitwise. In my example:
n=50, 110010, use n & 1 ==> 0 AND 1 instead of 110010 AND 1.
Is there a reason that c++ treats the bitwise and like this? My guess would be it has to do with the compiler ?

When we use bitwise and 1 (& 1) with a number we get back the same number.
No we don't. We get back the number consisting of the bits that are set in both the original number and in 1. Since only the lowest bit of 1 is set, the result is the lowest bit of the original number.
Now my question is how does c++ evaluates the following expression: n & 1.
If n is 50, then in binary:
n: 110010
1: 000001
n&1: 000000 // no bits set in both
If n is 51, then in binary:
n: 110011
1: 000001
n&1: 000001 // one bit set in both

From Wikipedia:
The bitwise AND operator is a single ampersand: &. It is just a representation of AND which does its work on the bits of the operands rather than the truth value of the operands. Bitwise binary AND does the logical AND (as shown in the table above) of the bits in each position of a number in its binary form.
In your example 110010 & 1, 1 is considered as 000001, and then each bit is anded and you get the result. In fact, I use this method: 1&number to check for even and odd numbers. This is how:
if(1 & num)
printf("it is odd");
else
printf("it is even");
This is how it works: suppose you have an 8 bit number. Now, the 8 bit notation of 1 will be 00000001.
If I now perform and on each bit, for all the first seven bits I will get 0, because it will be 0 & anything will be 0. Now, the last bit of 1 is 1. So, if my number also has last bit as 1, then 1 & 1 = 1, and if my last bit is 0, then 1 & 0 = 0.
When will the last bit in my number be 1? And when 0? When converting to decimal form, the last bit is multiplied by 20. And, 20 = 1. If this 1 is multiplied with 1, we get an odd number, and if it is multiplied with 0, we get an even number.

Related

Have some doubts in the operation [Bitwise Manipulation]

#include <iostream>
#include <math.h>
using namespace std;
// converting from decimal to binary
int main()
{
int n, bit, ans = 0, i = 0;
cout << "enter a number: ";
cin >> n;
while (n > 0)
{
bit = n & 1;
ans = round(bit * pow(10, i)) + ans; /* we used 'round' bcoz pow(10, 2) give 99.99999
it differs from compiler to compiler */
n = n >> 1;
i++;
}
cout << ans;
return 0;
}
I am unable to understand that in while(n>0), n will be stored as binary form or decimal form.
That is if n=5, so whether while loop check for (5>0) or (101>0).
Can anyone explain what is happening here?
I am new to this platform, please don't delete my question. My earlier questions are also gets deleted due enough dislikes. I am here to learn and am still learning.
"Decimal" and "Binary" are text representations of a value. n is an int, not text, so it holds the value 5. If I have 5 apples on a desk, then there is no "decimal" or "binary" involved. THere's just 5 apples. Same with int.
cin >> n;
while (n > 0)
This loop continues because 5 > 0.
n = n >> 1;
This is just a fancy way of writing n = n / 2, so then n becomes 2. Since 2 > 0, the loop continues. On the third run, n becomes 1, and since 1 > 0, the loop continues a third time. On the fourth run, n becomes 0, and 0 == 0, so the while loop exits.
Both n and ans are integers that your computer stores in a binary format. If n = 5 then n is both 5 and 0b0101. Your loop converts one integer n into a second integer ans which only uses the digits 1 and 0 and looks like the integer n in binary.
It does this by converting each power of two in n into a power of ten and adding it into ans. The integer 5 will become the integer 101 (one hundred and one).
In the loop, when you use the bitwise operator >> you are manipulating the underlying binary representation of the number directly, in this case, shifting all of the bits in the integer to the right and feeding in zeros on the left to replace the bits that have moved.
So, if n is 5 then:
0b0101 >> 1 gives 0b0010, or 2
0b0101 >> 2 gives 0b0001, or 1
0b0101 >> 3 gives 0b0000, or 0
When you use the bitwise operator & (bitwise and) you are again operating directly on the binary representation. This time you are and-ing all of the bits in one number with the bit in another number. For example:
0b01100110 & 0b10101110 = 0b00100110
0b01100110 & 0b10011001 = 0b00000000
In your loop you are doing four things:
1. bit = n & 1
And-ing the integer n with one will mean that bit is equal to:
1 when there is a 1 in the 2^0 place (the least significant bit) and,
0 when there is not a 1 in the 2^0 place.
2. ans = round(bit * pow(10, i)) + ans
You take 10^i and multiply it by bit. So:
bit is zero this is zero
if bit is one this is some power of ten.
3. n = n >> 1
Shift one place to the right. The bit that was in the 2^1 place is now in the 2^0 place.
4. i++
Increment i which tracks both your current power of 2 and current power of ten.
#Mooing Duck has explained it incredibly well. I'd just add that you are being confused about the Number System
Decimal numbers are called the base 10 numbers (digits: 0 - 9, total: 10)
Binary numbers are called the base 2 numbers(digits/bits: 0 - 1, total: 2)
101 (base 10) is very different from 101 (base 2)
When we use bitwise operators such as (<<, >>, &, ^, |) we manipulate the bits of the decimal (hence the name bitwise operators)
So, when you are doing 5 >> 1 you are actually doing 101 (base 2) >> 1 which results in 010 (base 2)
When you keep shifting the bits to the right(equivalent to dividing by 2), at one point you'll be left with no 1s and only 0s. And what's 0 (base 2)? Its 0(base 10). Hence, the loop breaks.

What does 0b1 mean in C++?

I came across a part of code that I cannot understand.
for (unsigned int i = (x & 0b1); i < x; i+= 2)
{
// body
}
Here, x is from 0 to 5.
What is meant by 0b1? and what would be the answers for eg: (0 & 0b1), (4 & 0b1) etc?
0b... is a binary number, just like 0x... is hex and 0... is octal.
Thus 0b1 is same as 1.
1b0 is illegal, the first digit in those must always be 0.
As previous answers said, it is the binary representation of the integer number 1, but they don't seem to have fully answered your question. This has a lot of layers so I'll briefly explain each.
In this context, the ampersand is working as a bitwise AND operator. i & 0b1 is (sometimes) a faster way of checking if an integer is even as opposed to i % 2 == 0.
Say you have int x = 5 and you'd like to check if it's even using bitwise AND.
In binary, 5 would be represented as 0101. That final 1 actually represents the number 1, and in binary integers it's only present in odd numbers. Let's apply the bitwise AND operator to 5 and 1;
0101
0001
&----
0001
The operator is checking each column, and if both rows are 1, that column of the result will be 1 – otherwise, it will be 0. So, the result (converted back to base10) is 1. Now let's try with an even number. 4 = 0100.
0100
0001
&----
0000
The result is now equal to 0. These rules apply to every single integer no matter its size.
The higher-level layer here is that in C, there is no boolean datatype, so booleans are represented as integers of either 0 (false) or any other value (true). This allows for some tricky shorthand, so the conditional if(x & 0b1) will only run if x is odd, because odd & 0b1 will always equal 1 (true), but even & 0b1 will always equal 0 (false).

Operations on bits, getting the bigger value

I'm not familiar with bitwise operations. I have this sequence:
1 0 0 0 0 : 16
---------------
0 1 1 1 1 : 15
---------------
0 1 1 1 0 : 14
---------------
.
.
.
---------------
0 0 0 1 1 : 3
---------------
0 0 0 1 0 : 2
---------------
0 0 0 0 1 : 1
---------------
I want to check first if there is more than one "1". If that's the case, I want to remove the one that has the bigger decimal value, and to finish, getting the bigger remaining. For example 15, there is four "1", I remove the bigger one, the "1" at "8", I got "0 0 1 1 1 : 7", where the bigger "1" is at "4". How can I do this?
Here's the code that does what you want:
unsigned chk_bits(unsigned int x) {
unsigned i;
if (x != 0 && (x & (x-1)) != 0) {
/* More than one '1' bit */
for (i = ~(~0U >> 1); (x & i) == 0; i >>= 1)
; /* Intentionally left blank */
return x & ~i;
}
return x;
}
Note that I assume you're dealing with unsigned numbers. This is usually safer, because right shifting is implementation defined on signed integers, because of sign extension.
The if statement checks if there's more than one bit set in x. x & (x-1) is a known way to get a number that is the same as x with the first '1' least significant bit turned off (for example, if x is 101100100, then x & (x-1) is 101100000. Thus, the if says:
If x is not zero, and if turning off the first bit set to 1 (from LSB to MSB) results in something that is not 0,
then...
Which is equivalent to saying that there's m ore than 1 bit set in x.
Then, we loop through every bit in x, stopping in the first most significant bit that is set. i is initialized to 1000000000000000000000000000, and the loop keeps right shifting it until x & i evaluates to something that is not zero, at which point we found the first most significant bit that is 1. At that point, taking i's complement will yield the mask to turn off this bit in x, since ~i is a number with every bit set to 1 except the only bit that was a 1 (which corresponds to the highest order bit in x). Thus, ANDing this with x gives you what you want.
The code is portable: it does not assume any particular representation, nor does it rely on the fact that unsigned is 32 or 64 bits.
UPDATE: I'm adding a more detailed explanation after reading your comment.
1st step - understanding what x & (x-1) does:
We have to consider two possibilities here:
x ends with a 1 (.......0011001)
x ends with a 0 (.......0011000)
In the first case, it is easy to see that x-1 is just x with the rightmost bit set to 0. For example, 0011001 - 1 = 0011000, so, effectively, x & (x-1) will just be x-1.
In the second case, it might be slightly harder to understand, but if the rightmost bit of x is a 0, then x-1 will be x with every 0 bit switched to a 1 bit, starting on the least significant bits, until a 1 is found, which is turned into a 0.
Let me give you an example, because this can be tricky for someone new to this:
1101011000 - 1 = 11101010111
Why is that? Because the previous number of a binary number ending with a 0 is a binary number filled with one or more 1 bits in the rightmost positions. When we increment it, like 10101111101111 + 1, we have to increment the next "free" position, i.e., the next 0 position, to turn it into a 1, and then all of the 1-bits to the right of that position are turned into 0. This is the way ANY base-n counting works, the only difference is that for base-2 you only have 0's and 1's.
Think about how base-10 counting works. When we run out of digits, the value wraps around and we add a new digit on the left side. What comes after 999? Well, the counting resets again, with a new digit on the left, and the 9's wrap around to 0, and the result is 1000. The same thing happens with binary arithmetic.
Think about the process of counting in binary; we just have 2 bits, 0 and 1:
0 (decimal 0)
1 (decimal 1 - now, we ran out of bits. For the next number, this 1 will be turned into a 0, and we need to add a new bit to the left)
10 (decimal 2)
11 (decimal 3 - the process is going to repeat again - we ran out of bits, so now those 2 bits will be turned into 0 and a new bit to the left must be added)
100 (decimal 4)
101 (decimal 5)
110 (the same process repeats again)
111
...
See how the pattern is exactly as I described?
Remember we are considering the 2nd case, where x ends with a 0. While comparing x-1 with x, rightmost 0's on x are now 1's in x-1, and the rightmost 1 in x is now 0 in x-1. Thus, the only part of x that remains the same is that on the left of the 1 that was turned into a 0.
So, x & (x-1) will be the same as x until the position where the first rightmost 1 bit was. So now we can see that in both cases, x & (x-1) will in fact delete the rightmost 1 bit of x.
2nd step: What exactly is ~0U >> 1?
The letter U stands for unsigned. In C, integer constants are of type int unless you specify it. Appending a U to an integer constant makes it unsigned. I used this because, as I mentioned earlier, it is implementation defined whether right shifting makes sign extension. The unary operator ~ is the complement operator, it grabs a number, and takes its complement: every 0 bit is turned into 1 and every 1 bit is turned into 0. So, ~0 is a number filled with 1's: 11111111111.... Then I shift it right one position, so now we have: 01111111...., and the expression for this is ~0U >> 1. Finally, I take the complement of that, to get 100000...., which in code is ~(~0U >> 1). This is just a portable way to get a number with the leftmost bit set to 1 and every other set to 0.
You can give a look at K&R chapter 2, more specifically, section 2.9. Starting on page 48, bitwise operators are presented. Exercise 2-9 challenges the reader to explain why x & (x-1) works. In case you don't know, K&R is a book describing the C programming language written by Kernighan and Ritchie, the creators of C. The book title is "The C Programming Language", I recommend you to get a copy of the second edition. Every good C programmer learned C from this book.
I want to check first if there is more than one "1".
If a number has a single 1 in its binary representation then it is a number that can be represented in the form 2x. For example,
4 00000100 2^2
32 00010000 2^5
So to check for single one, you can just check for this property.
If log2 (x) is a whole number then it has single 1 in it's binary representation.
You can calculate log2 (x)
log2 (x) = logy (x) / logy (2)
where y can be anything, which for standard log functions is either 10 or e.
Here is a solution
double logBase2 = log(num)/log(2);
if (logBase2 != (int)logBase2) {
int i = 7;
for (;i >0 ; i--) {
if (num & (1 << i)) {
num &= ~(1 << i);
break;
}
}
}

Please explain in detail the logic behind the output of x &(~0 << n)

I have doubt in logic behind x &(~0 <<n).
First of all I could not get the meaning of ~0. When I tried this in Java it showed -1. How
can we represent -1 in binary and differentiate it from the positive numbers?
The most common way (and the way that Java uses) to represent negative numbers, is called Two's Complement. As mentioned in my comment, one way to calculate the negative in this system is -x = ~(x - 1). An other, equivalent way, is -x = ~x + 1.
For example, in 8bit,
00000001 // 1
00000000 // 1 - 1
11111111 // ~(1 - 1) = ~0 = -1
Adding one to 11111111 would wrap to zero - it makes sense to call "the number such that adding one to it result in zero" minus one.
The numbers with the highest bit set are regarded as negative.
The wikipedia article I linked to contains more information.
As for x & (~0 << n), ~0 is just a way to represent "all ones" (which also happens to be -1, which is irrelevant for this use really). For most n, "all ones" shifted left by n is a bunch of ones followed by n zeroes.
In total, that expression clears the lower n bits of x.
At least, for 0 <= n <= 31.
a << n in Java, where a is an int, is equivalent to a << (n & 31).
Every bit of the byte 0 is 0, and every bit of -1 is 1, so the bitwise negation of 0 is -1.
Hence ~0 is -1.
As for the rest of the question: what are you actually asking?

Access individual bits in a char c++

How would i go about accessing the individual bits inside a c++ type, char or any c++ other type for example.
If you want access bit N:
Get: (INPUT >> N) & 1;
Set: INPUT |= 1 << N;
Unset: INPUT &= ~(1 << N);
Toggle: INPUT ^= 1 << N;
You would use the binary operators | (or), & (and) and ^ (xor) to set them. To set the third bit of variable a, you would type, for instance: 
a = a | 0x4
// c++ 14
a = a | 0b0100
Note that 4’s binary representation is 0100
That is very easy
Lets say you need to access individual bits of an integer
Create a mask like this
int mask =1;
now, anding your numberwith this mask gives the value set at the zeroth bit
in order to access the bit set at ith position (indexes start from zero) , just and with (mask<
If you want to look at the nth bit in a number you can use: number&(1<<n).
Essentially the the (1<<n) which is basically 2^n(because you shift the 1 bit in ...0001 n times, each left shift means multiply by 2) creates a number which happens to be 0 everywhere but 1 at the nth position(this is how math works).
You then & that with number. This returns a number which is either 0 everywhere or a number that has a 1 somewhere(essentially an integer which is either 0 or not).
Example:
2nd bit in in 4, 4&(1<<2)
0100
& 0010
____
0000 = 0
Therefore the 2nd bit in 4 is a 0
It will also work with chars because they are also numbers in C,C++