I am receiving a number N where N is a 4-bit integer and I need to change its LSB to 1 without changing the other 3 bits in the number using C.
Basically, all must read XXX1.
So lets say n = 2, the binary would be 0010. I would change the LSB to 1 making the number 0011.
I am struggling with finding a combination of operations that will do this. I am working with: !, ~, &, |, ^, <<, >>, +, -, =.
This has really been driving me crazy and I have been playing around with >>/<< and ~ and starting out with 0xF.
Try
number |= 1;
This should set the LSB to 1 regardless of what the number is. Why? Because the bitwise OR (|) operator does exactly what its name suggests: it logical ORs the two numbers' bits. So if you have, say, 1010b and 1b (10 and 1 in decimal), then the operator does this:
1 0 1 0
OR 0 0 0 1
= 1 0 1 1
And that's exactly what you want.
For your information, the
number |= 1;
statement is equivalent to
number = number | 1;
Use x = x | 0x01; to set the LSB to 1
A visualization
? ? ? ? ? ? ? ?
OR
0 0 0 0 0 0 0 1
----------------------
? ? ? ? ? ? ? 1
Therefore other bits will stay the same except the LSB is set to 1.
Use the bitwise or operator |. It looks at two numbers bit by bit, and returns the number generated by performing an OR with each bit.
int n = 2;
n = n | 1;
printf("%d\n", n); // prints the number 3
In binary, 2 = 0010, 3 = 0011, and 1 = 0001
0010
OR 0001
-------
0011
If n is not 0
n | !!n
works.
If n is 0, then !n is what you want.
UPDATE
The fancy one liner :P
n = n ? n | !!n : !n;
Related
I have a question: Is bitwise anding transitive, particularly in C and C++?
Say res=(1 & 2 & 3 & 4), is this same as res1=(1&2) and res2=(3&4) and
res= (res1 & res2). Will this be same?
Yes, bitwise AND is transitive as you've used the term.
It's perhaps easier to think of things as a stack of bits. So if we have four 4-bit numbers, we can do something like this:
A = 0xB;
B = 0x3;
C = 0x1;
D = 0xf;
If we simply stack them up:
A 1 0 1 1
B 0 0 1 1
C 0 0 0 1
D 1 1 1 1
Then the result of a bitwise AND looks at one column at a time, and produces a 1 for that column if and only if there's a 1 for every line in that column, so in the case above, we get: 0 0 0 1, because the last column is the only one that's all ones.
If we split that in half to get:
A 1 0 1 1
B 0 0 1 1
A&B 0 0 1 1
And:
C 0 0 0 1
D 1 1 1 1
C&D 0 0 0 1
Then and those intermediate results:
A&B 0 0 1 1
C&D 0 0 0 1
End 0 0 0 1
Our result is still going to be the same--anywhere there's a zero in a column, that'll produce a zero in the intermediate result, which will produce a zero in the final result.
The term you're looking for is associative. We generally wouldn't call a binary operator "transitive". And yes, & and | are both associative, by default. Obviously, you could overload the operators to be something nonsensical, but the default implementations will be associative. To see this, consider one-bit values a, b, and c and note that
(a & b) & c == a & (b & c)
because both will be 1 if and only if all three inputs are 1. And this is the operation that is being applied pointwise to each bit in your integer values. The same is true of |, simply replacing 1 with 0.
There are also some issues to consider if your integers are signed, as the behavior is dependent on the underlying bit representation.
This question already has answers here:
How do I set, clear, and toggle a single bit?
(27 answers)
Closed 5 years ago.
For example, if I want to set a bit in y at position n (in C)
y = y | (1 << n)
But if I want to delete a bit in y at position n I have to use the ~ operator after binary AND.
y = y & ~(1 << n);
My question: Why Must I use the ~ operator?
Is this because the result turns into negative area?
If you want to set a bit at third place from the right :
Y : 01001000
1 << 2 : 00000100
Y | (1 << 2) : 01001100 The | is OR, bits are set to 1 if any is 1.
If you want to remove the bit :
1 << 2 : 00000100
~(1 << 2) : 11111011 The ~ is NOT, bits are inversed
Y : 01001100
Y & ~(1 << 2) : 01001000 The & is AND, bits are set to 1 if both are 1.
I suggest you read more about Bitwise operators
No, ~ has nothing to do with interpreting the number as negative: tilde ~ operator interprets the number as a pattern of bits, which it then inverts (i.e. replaces zeros with ones and ones with zeros). In fact, if you apply ~ to an unsigned value, the result would remain positive.
Recall that 1 << k expression produces a pattern of all zeros and a single 1 at the position designated by k. This is a bit mask that can be used to force bit at position k to 1 by applying OR operation.
Now consider what happens when you apply ~ to it: all 0s would become 1s, and the only 1 would become zero. Hence, the result is a bit mask suitable for forcing a single bit to zero by applying AND operation.
The ~ operator turns all of the 0's to 1's and all of the 1's to 0's. In order to clear the bint in position n you want to and it will all ones and a zero in the nth position so shift a one to the nth position and ~ invert all the bits.
1 << n for n==3 (just an example) gives you a pattern 0000000...0001000. ~ negates the bit
pattern to 11111111....11110111. Using the bitwise AND operator (&) will
only set the required bit to 0, all other remain with the same value. It's using
the fact that for a bit b: b & 1 == b.
~ flips all bits, it has nothing to do with negative numbers.
A graphical representation for a sequence of k-bits
pos k-1 k-2 0
+---+---+-------------------+---+---+
1: | 0 | 0 | ··· | 0 | 1 |
+---+---+-------------------+---+---+
pos k-1 k-2 n n-1 0
+---+---+-----+---+---+---+-----+---+
1<<n | 0 | 0 | ··· | 1 | 0 | 0 | ··· | 0 |
+---+---+-----+---+---+---+-----+---+
pos k-1 k-2 n n-1 0
+---+---+-----+---+---+---+-----+---+
~(1<<n) | 1 | 1 | ··· | 0 | 1 | 1 | ··· | 1 |
+---+---+-----+---+---+---+-----+---+
So I saw this code which printed out individual bits of any number.I do not understand why the individual bits are accessed and not the entire number itself
#include <stdio.h>
int main()
{
int x=10, b;
for(b=0; x!=0; x>>=1) {
printf("%d:%d\n", b, (x&1));
b++;
}
}
OUTPUT:
0:0
1:1
2:0
3:1
Please help me understand this piece of code.
In your code you are printing the value of X variable in binary. For this, your code, use logical operation as AND operator and right-shift.
In the loop condition, you displace the X variable one bit to the right.
for b = 0 you get x = 1010
for b = 1 you get x = 101
for b = 2 you get x = 10
for b = 3 you get x = 1
Then, in your print, show your loop iterator (b) and your X variable AND 1.
The AND operator get this values:
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1
In your case, you have:
1010 AND (000)1 = 0
101 AND (00)1 = 1
10 AND (0)1 = 0
1 AND 1 = 1
There are two questions in your post: how to access an individual bit ? and how to select that bit ?
Concerning the first question, suppose you want to access the less significant bit (or, to make it simpler, the rightmmost bit), you can use a mask: suppose your data is b0011 for instance, you can mask with b0001 (i.e. 1 in decimal).
0 0 1 1
& 0 0 0 1
---------
0 0 0 1
The & operator is the bitwise and. If you look in your code sample, you have printf("%d:%d\n", b, (x&1)); in which you can see x & 1, i.e. print the rightmost bit of x.
Now comes the second question: how to put each bit in the rightmost position one after each other (said otherwise, how to select the bit to print) ? An easy solution is to shift your data of 1 position to the right each time you want to select the next bit (i.e. the bit to the left of the current one).
In C, you can shift using >>. For instance, if x is b0011, then x >> 1 is b0001 (in this case, you fill the leftmost position with zeros, but in some cases it might be trickier). If you look in you code sample, you have x>>=1 in the for-loop, which assigns x >> 1 in x.
Hence, suppose you take the previous example:
0 0 1 1 = x 0 0 0 1 = x
& 0 0 0 1 & 0 0 0 1
--------- x >> 1 = b0001 -> x ---------
0 0 0 1 0 0 0 1
and so one...
A last bonus point, the loop stopping condition is x != 0, this implies that you don't prints all bits of your data, but only the bits up to the leftmost 1 (included). For instance, in the above example, after printing the two rightmost bits, x becomes 0 and the loop exits.
I don't understand the exercise 2-9, in K&R C programming language,
chapter 2, 2.10:
Exercise 2-9. In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x . Explain why. Use this observation to write a faster version of bitcount .
the bitcount function is:
/* bitcount: count 1 bits in x */
int bitcount(unsigned x)
{
int b;
for (b = 0; x != 0; x >>= 1)
if (x & 01)
b++;
return b;
}
The function deletes the rightmost bit after checking if it is bit-1 and then pops in the last bit .
I can't understand why x&(x-1) deletes the right most 1-bit?
For example, suppose x is 1010 and x-1 is 1001 in binary, and x&(x-1) would be 1011, so the rightmost bit would be there and would be one, where am I wrong?
Also, the exercise mentioned two's complement, does it have something to do with this question?
Thanks a lot!!!
First, you need to believe that K&R are correct.
Second, you may have some mis-understanding on the words.
Let me clarify it again for you. The rightmost 1-bit does not mean the right most bit, but the right most bit which is 1 in the binary form.
Let's arbitrary assume that x is xxxxxxx1000(x can be 0 or 1). Then from right to left, the fourth bit is the "rightmost 1-bit". On the basis of this understanding, let's continue on the problem.
Why x &=(x-1) can delete the rightmost 1-bit?
In a two's complement number system, -1 is represented with all 1 bit-pattern.
So x-1 is actually x+(-1), which is xxxxxxx1000+11111111111. Here comes the tricky point.
before the righmost 1-bit, all 0 becomes 1 and the rightmost 1-bit becomes 0 and there is a carry 1 go to left side. And this 1 will continue to proceed to the left most and cause an overflow, meanwhile, all 'x' bit is still a because 'x'+'1'+'1'(carry) causes a 'x' bit.
Then x & (x-1) will delete the rightmost 1-bit.
Hope you can understand it now.
Thanks.
Here is a simple way to explain it. Let's arbitrarily assume that number Y is xxxxxxx1000 (x can be 0 or 1).
xxxxxxx1000 - 1 = xxxxxxx0111
xxxxxxx1000 & xxxxxxx0111 = xxxxxxx0000 (See, the "rightmost 1" is gone.)
So the number of repetitions of Y &= (Y-1) before Y becomes 0 will be the total number of 1's in Y.
Why do x & (x-1) delete the right most order bit? Just try and see:
If the righmost order bit is 1, x has a binary representation of a...b1 and x-1 is a...b0 so the bitwise and will give a...b1 because common bits are left unchanged by the and and 1 & 0 is 0
Else x has a binary representation of a...b10...0; x-1 is a...b01...1 and for same reason as above x & (x-1) will be a...b00...0 again clearing the rightmost order bit.
So instead of scanning all bits to find which one are 0 and which one are 1, you just iterate the operation x = x & (x-1) until x is 0: the number of steps will be the number of 1 bits. It is more efficient than the naive implementation because statistically you will use half number of steps.
Example of code:
int bitcount(unsigned int x) {
int nb = 0;
while (x != 0) {
x &= x-1;
nb++
}
return nb;
}
Ik I'm already very late (≈ 3.5yrs) but your example has mistake.
x = 1010 = 10
x - 1 = 1001 = 9
1010 & 1001 = 1000
So as you can see, it deleted the rightmost bit in 10.
7 = 111
6 = 110
5 = 101
4 = 100
3 = 011
2 = 010
1 = 001
0 = 000
Observe that the position of rightmost 1 in any number, the bit at that same position of that number minus one is 0. Thus ANDing x with x-1 will be reset (i.e. set to 0) the rightmost bit.
7 & 6 = 111 & 110 = 110 = 6
6 & 5 = 110 & 101 = 100 = 4
5 & 4 = 101 & 100 = 100 = 4
4 & 3 = 010 & 011 = 010 = 2
3 & 2 = 011 & 010 = 010 = 2
2 & 1 = 010 & 001 = 000 = 0
1 & 0 = 001 & 000 = 000 = 0
I want to ask about C operator from this code. My friends ask it, but I never seen this operator:
binfo_out.biSizeImage = ( ( ( (binfo_out.biWidth * binfo_out.biBitCount) + 31) & ~31) / 8) * abs(out_bi.biHeight);
What this operator & ~31 mean? anybody can explain this?
The & operator is a bitwise AND. The ~ operator is a bitwise NOT (i.e. inverts the bits). As 31 is binary 11111, ~31 is binary 1111111....111100000 (i.e. a number which is all ones, but has five zeroes at the end). Anding a number with this thus clears the least significant five bits, which (if you think about it) rounds down to a multiple of 32.
What does the whole thing do? Note it adds 31 first. This has the effect that the whole thing rounds something UP to the next multiple of 32.
This might be used to calculate (for instance), how many bits are going to be used to store something if you can only use 32 bit quantities to store them, as there is going to be some wastage in the last 32 bit number.
31 in binary representation will be 11111 so ~31 = 5 zeros 00000 preceeded by 1's. so it is to make last 5 bits zero. i.e. to mask the last 5 bits.
here ~ is NOT operator i.e. it gives 1's complement. and & is AND operator.
& is the bitwise AND operator. It and's every corresponding bit of two operands on its both sides. In an example, it does the following:
Let char be a type of 8 bits.
unsigned char a = 5;
unsigned char b = 12;
Their bit representation would be as follows:
a --> 0 0 0 0 0 1 0 1 // 5
b --> 0 0 0 0 1 1 0 0 // 12
And the bitwise AND of those would be:
a & b --> 0 0 0 0 0 1 0 0 // 8
Now, the ~ is the bitwise NOT operator, and it negates every single bit of the operand it prefixes. In an example, it does the following:
With the same a from the previous example, the ~a would be:
~a --> 1 1 1 1 1 0 1 0 // 250
Now with all this knowledge, x & ~31 would be the bitwise AND of x and ~31, where the bit representation of ~31 looks like this:
~31 --> 1111 1111 1111 1111 1111 1111 1110 0000 // -32 on my end
So the result would be whatever the x has on its bits, other than its last 5 bits.
& ~31
means bitwise and of the operand on the left of & and a bitwise not of 31.
http://en.wikipedia.org/wiki/Bitwise_operation
The number 31 in binary is 11111 and ~ in this case is the unare one's compliment operator. So assuming 4-byte int:
~31 = 11111111 11111111 11111111 11100000
The & is the bitwise AND operator. So you're taking the value of:
((out_bi.biWidth * out_bi.biBitCount) + 31)
And performing a bitwise AND with the above value, which is essentially blanking the 5 low-order bits of the left-hand result.