Right shift with bitwise AND - c

A solution from a top answer is
To check a bit, shift the number x to the right, then bitwise AND it:
bit = (number >> x) & 1;
That will put the value of bit x into the variable bit.
What confuses me is this, when assuming the following:
unsigned number = 5; //0101
int x = 2; //
After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:
bit = (number >> (x - 1)) & 1);

Yes, you are doing the bitwise AND against the third bit. Consider x to be zero-indexed, i.e. the first bit is bit 0.

You said:
After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:
bit = (number >> (x - 1)) & 1);
To get the value of the 1st least significant bit, you need (number >> 0) & 1.
To get the value of the 2nd least significant bit, you need (number >> 1) & 1.
To get the value of the 3rd least significant bit, you need (number >> 2) & 1.
etc.
In other words,
1st implies 0 bits to shift
2nd implies 1 bits to shift
3rd implies 2 bits to shift
Nth implies N-1 bits to shift
I hope that makes it a little bit clearer for you.

The bit number represents the power of two. Thus when x is two, you are talking about bit 2 = 2**2 = 4.
The least-significant bit (or 'right most' bit if you prefer it bit 0, not bit 1.
Also, there is no reason to actually do the bit shift unless your 'bit number' is in a variable.
For example, to test bit 5 of a value, simply do
if (variable & 0x20)
bit_is_set();
Here 0x20 is simply 2**5, (or 1 << 5)

Related

How to set masked bits to a specified number?

I haven't been able to find an answer to this on Google, nor do I have any better search ideas. If I have a 2 byte number, a mask, and a third number, how do I replace the masked bits with the third number. For example if I have 0xABCD, the mask 0x0F00, and third number 4 - I would like to replace B with 4 to get A4CD. In other words, I want to be able to replace arbitrary bits selected by a mask with the bits of another arbitrary number (we are assuming that the number replacing the bits fits - i.e. if I mask 5 bits, the number to replace those 5 bits requires 5 bits or less to represent.)
The goal is to replace the bits of number selected by mask with those of value, shifted appropriately, assuming value does not exceed the target range.
Masking off the target bits is easy: number &= ~mask; achieves that simply.
The tricky part is to shift value to the left by the number of zero bits in mask below the set ones. You can write a loop for this.
Here is a simple implementation:
unsigned set_bits(unsigned number, unsigned mask, unsigned value) {
// assuming mask != 0
number &= ~mask;
while (!(mask & 1)) {
value <<= 1;
mask >>= 1;
}
return number | value;
}
You can compute the shift value as a multiplier this way: subtracting one from the mask sets all its 0 low bits to 1, or-ing this value with mask sets all low bits to 1 and xor-ing with mask yields a mask with just the low bits set. Adding 1 to this mask gives the power of 2 by which to multiply value to shift it in place. This works also if there are no 0 bits in the low order bits of mask.
As commented by aschepler, (A ^ (A | B)) == (~A & B) so the expression ((mask ^ (mask | (mask - 1))) + 1) can be simplified as (((mask - 1) & ~mask) + 1).
An elegant simplification was provided by Falk Hüffner: (((mask - 1) & ~mask) + 1) is just mask & -mask.
Here is a branchless version using this trick:
unsigned set_bits(unsigned number, unsigned mask, unsigned value) {
return (number & ~mask) | (value * (mask & -mask));
}
Making this an inline function may help the compiler generate optimal code for constant mask values.

C expression that sets the last n bits of int variable to zero

In other words, sets the last 5 bits of integer variable x to zero, also it must be in a portable form.
I was trying to do it with the << operator but that only moves the bits to the left, rather than changing the last 5 bits to zero.
11001011 should be changed to 11000000
Create a mask that blanks out that last n integers if it is bitwise-ANDed with your int:
x &= ~ ((1 << n) - 1);
The expression 1 << n shifts 1 by n places and is effectively two to the power of n. So for 5, you get 32 or 0x00000020. Subtract one and you get a number that as the n lowest bits set, in your case 0x0000001F. Negate the bits with ~ and you get 0xFFFFFFE0, the mask others have posted, too. A bitwise AND with your integer will keep only the bits that the mask and your number have in common, which can only bet bits from the sixth bit on.
For 32-bit integers, you should be able to mask off those bits using the & (bitwise and) operator.
x & 0xFFFFFFE0.
http://en.wikipedia.org/wiki/Bitwise_operation#AND
You can use bitwise and & for this
int x = 0x00cb;
x = x & 0xffe0;
This keeps the higher bits and sets the lower bits to zero.

how do I set up an if statement

How would I go about setting up an if statement using only the following bitwise operations:
!
~
&
^
|
&plus;
<<
>>
As an example: "if x is negative then add 15"
This would mean that if the input was x = 0xF0000000, then we would produce 0xF000000F. If the input was x = 0x00000004, we would produce 0x00000004.
You can add 15 to a number if it is negative, and 0 otherwise as follows. Shifting a negative number right will shift in 1's if the value is negative, and 0's otherwise. Shifting by 31 will fill the int with either 1's or 0's. ANDing by 0xF will set the summand to 15 if it is negative, and 0 otherwise, resulting in no change to x.
x += (x >> 31) & 0xF;
If you're worried about the implementation dependent behavior of shifting a signed number to the right. You can do the same thing with the following code, however you still are depending on a two's complement representation of the number. The shift results in 0 or 1, the multiplication scales the number to the appropriate value.
x += (((unsigned)x >> 31) * 0xF);

Separating the Nybbles in a Byte with Bitwise Operators in C

If we have a decimal value: 123
and its binary version: 01111011
How can I get four leftmost and the four rightmost bits from this byte into 2 separate int variables?
I mean:
int a = 7; // 0111 (the first four bits from the left)
int b = 11; // 1011 (the first four bits from the right)
Much appreciated!
int x = 123;
int low = x & 0x0F;
int high = (x & 0xF0) >> 4;
This is called masking and shifting. By ANDing with 0xF (which is binary 00001111) we remove the higher four bits. ANDing with 0xF0 (which is binary 11110000) removes the lower four bits. Then (in the latter case), we shift to the right by 4 bits, in effect, pushing away the lower 4 bits and leaving only what were the upper 4 bits.
As #owlstead says in the comments below, there's another way to get the higher bits. Instead of masking the lower bits then shifting, we can just shift.
int high = x >> 4;
Note that we don't need to mask the lower bits since whatever they were, they're gone (we've pushed them out). The above example is clearer since we explicitly zero them out first, but there's no need to do so for this particular example.
But to deal with numbers bigger than 16 bits (int is usually 32 bits), we still need to mask, because we can have the even higher sixteen bits getting in the way!
int high = (x >> 4) & 0x0F;

How do I get the lower 8 bits of an int?

Lets say I have an int variable n = 8. On most machines this will be a 32 bit value. How can I only get the lower 8 bits (lowest byte) of this in binary? Also how can I access each bit to find out what it is?
unsigned n = 8;
unsigned low8bits = n & 0xFF;
Note a few things:
For bitwise operations, always use the unsigned types
Bits can be extracted from numbers using binary masking with the & operator
To access the low 8 bits the mask is 0xFF because in binary it has its low 8 bits turned on and the rest 0
The low 8 bits of the number 8 are... 8 (think about it for a moment)
To access a certain bit of a number, say the kth bit:
unsigned n = ...;
unsigned kthbit = (1 << k) & n;
Now, kthbit will be 0 if the kth bit of n is 0, and some positive number (2**k) if the kth bit of n is 1.
Use bitwise arithmetic to mask off the lowest 8 bits:
unsigned char c = (x & 0xFF);
To access the nth lowest bit, the equation is (x & (1 << n)) (n of zero indicates the least significant bit). A result of zero indicates the bit is clear, and non-zero indicates the bit is set.
The best way is to use the bit logical operator & with the proper value.
So for the lower 8 bits:
n & 0xFF; /* 0xFF == all the lower 8 bits set */
Or as a general rule:
n & ((1<<8)-1) /* generate 0x100 then subtract 1, thus 0xFF */
You can combine with the bit shift operator to get a specific bit:
(n & (1<<3))>>3;
/* will give the value of the 3rd bit - note the >>3 is just to make the value either 0, or 1, not 0 or non-0 */
You can test if a particular bit is set in a number using << and &, ie:
if (num & (1<<3)) ...
will test if the fourth bit is set or not.
Similarly, you can extract just the lowest 8 bits (as an integer) by using & with a number which only has the lowest 8 bits set, ie num & 255 or num & 0xFF (in hexadecimal).

Resources