Take the last 2 bits of a nibble in C - c

I have this byte: 10111011 and i want to split into 2 nibble (msb and lsb).After that i want to take the last 2 bits from the lsb (so i want 11 from 1011).
I know that:
With 10011011 >> 4 i get the msb (1001)
With 10011011 & 0xf i get the lsb (1011)
Now what can i do to take the 11 from lsb 1011?

Just the same: bits = lsb & 0x03

The bitmask for the first two bits is 3, so simply use:
int val = x & 3;
Since the bits are already in the proper position you don't need some shift operator.
For the above value it would be.
val = (x >> 4) & 3;

You'd do:
foo & 0x03
Where foo is the bit-pattern you want masked.

Related

How does this bits reversion in a byte work?

I'm new to programming and I found this method to reverse bits in a byte in C:
//(10000011) -> (11000001)
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
posted by an user in answer to this question, but I can't understand how it works. What do these constants mean?
It might help to look at the binary representation of the above numbers:
0xF0: 11110000
0x0F: 00001111
0xCC: 11001100
0x33: 00110011
0xAA: 10101010
0x55: 01010101
The first pair of numbers are used to mask out and swap the first 4 bits and the last 4 bits of a byte.
The second pair masks out and swaps the first 2 bits and last 2 bits of a set of 4 bits.
The third pair masks out and swap adjacent pairs of bits.
The code first swaps the "nibbles", i.e. most significant 4 bits with least significant 4 bits. Then it swaps two top order pairs together, and bottom pairs together; finally it does pairwise swaps of 2n and 2n+1 bits.
I am going to denote the bits of the original value of b here by their exponent, in angle brackets (this is just a pseudo notation that I am using here, not correct C); I use o to mark any bit that is 0 always. So in the beginning we have
<76543210>
No in the first operation we have
<76543210> & 0xF0 -> <7654oooo>
<76543210> & 0x0F -> <oooo3210>
Now the former is shifted right by 4 bits, and the latter left by 4, thus we get
<7654oooo> >> 4 -> <oooo7654>
<oooo3210> << 4 -> <3210oooo>
Finally these are or'ed together, and thus after the statement
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
the value of b is the permutation <32107654> of the original bits.
In the second statement the mask 0xCC is 11001100 in binary, and 0x33 is 00110011 in binary; the intermediate values are:
(<32107654> & 0xCC) >> 2 -> <32oo76oo> >> 2 -> <oo32oo76>; and
(<32107654> & 0x33) << 2 -> <oo10oo54> << 2 -> <10oo54oo>.
These 2 or'ed together will result in permutation <10325476>. Now finally, the mask 0xAA is 10101010 in binary, and 0x55 is 01010101. Thus we have
(<10325476> & 0xAA) >> 1 -> <1o3o5o7o> >> 1 -> <o1o3o5o7>; and
(<10325476> & 0x55) << 1 -> <o0o2o4o6> << 1 -> <0o2o4o6o>
These or'ed together will result in permutation <01234567> which is the reverse of the original.
So it's just a lot of bit shifting. The bits are in the following order:
76543210
Now, first line, first part keeps high bits, sets lower bits to 0 (mask is 0b11110000), shifts them 4 to the right. Second part does the same for the lower bits (mask is 0b00001111), and shifts to the left:
first line, first part: 7654xxxx => xxxx7654 (bits shift to the right)
first line, second part: xxxx3210 => 3210xxxx (bits shift to the left)
add them together: => 32107654
Then, second line. Same action, different masks (0b11001100 and 0b00110011, respectively), with 32107654:
second line, first part: 32xx76xx => xx32xx76 (bits shift to the right)
second line, second part: xx10xx54 => 10xx54xx (bits shift to the left)
add them together: => 10325476
Third line is the same with a again other masks(0b10101010 and 0b01010101, respectively), with 10325476:
third line, first part: 1x3x5x7x => x1x3x5x7 (bits shift to the right)
third line, second part: x0x2x4x6 => 0x2x4x6x (bits shift to the left)
add them together: => 01234567
So we end up, finally, with the action:
76543210 => 01234567
Let's number the bits in b as follows:
01234567
0xF0 in binary is 11110000, and 0x0F is 00001111. The first assignment shifts the leftmost 4 bits to the right, and the rightmost 4 bits to the left, then combines them with OR, so the result is:
45670123
0xCC is 11001100, and 0x33 is 00110011. When these masked bits are shifted by 2 bits and combined, the result is:
67452301
Finally, 0xAA is 10101010 and 0x55 is 01010101. When these masks and shifts are done, the result is:
76543210
Voila! this is the reversed order.
Notice that for each pair of shifts, the bit masks are inverses of each other, and the number of bits being shifted are the same as the length of the sequences of 1 bits in the mask. So each of them is swapping groups of bits whose size is that sequence length.
You need to understand 4 main things in order to understand what above code means.
& (AND) Bitwise Operator.
| (OR) Bitwise Operator.
>> (Right Shift Operator).
<< (Left Shift Operator).
Luckily, I just have written a detailed blog that explains everything about Number System and Bit Manipulation

how to set 3 lower bits of uint8_t in C

I would like to set the 3 lower bites of uint8_t with value 3.
I've tried the following:
uint8_t temp = some_value;
temp = temp & 0x3
but this does not work....
To set bits you need |:
temp = temp | 0x3;
or more compactly:
temp |= 0x3;
If you want to set a 3-bit span to the number 3, you need to both set and clear bits:
temp &= ~0x7; // clear bits
temp |= 0x3; // set bits
To set the three lower bits you need to set the mask 0x07, because 7 represented in binary is 00000111.
If you want to get a mask of lower bits by specifying the number of bits, you can use this formula:
int bits = 3; // 3 lower bits
uint8_t mask = (1 << bits) - 1; // 7
To clear the pre-existing value of those bits, use a negative of the mask with the bitwise operator "and":
temp = temp & ~mask; // mask is 00000111
// ~mask is 11111000 (negative)
// this operation zero out the 3 last bits of temp
And then you assign a new value to those bits with the bitwise operator "or":
temp = temp | (new_value & mask); // applying mask to new_value to make
// sure its within the bit limit
& 3 is logical and, it will clear all bits except two lowest. You want to or also.
So to set three lowest bits to three, you would use temp = (temp & ~7) | 3. ~ is a logical not, which turns 7 into "all other bits than the last three", which when used with and will clear the three bits. After that or the 3 into it.
This will change the 3 lower bits of z to 011 (3), while preserving the upper 5 bits:
uint8_t z = something();
z = (z & ~7) | 3;
After this, the bits of z will look like this, where x means "unknown":
xxxxx011

Extracting 4 bits from N to N+4 in unsigned long

Consider the following integer:
uint32_t p = 0xdeadbeef;
I want to get:
0..3 bits so I did:
p & ((1 << 4) - 1); and that went good.
however, for 4..7 what I tried did not go as expected:
(p >> 16) & 0xFFFF0000
Why would it not extract the bits I want? Am I not moving p 16 positions to the right and then taking out 4 bits?
Would really appreciate an answer with explanation, thanks!
If you want to get bits from 4..7
(p>>4) & 0xf
If you want to get bits from N to (N+4-1)
(p>>N) & 0xf
And N should be <32 (if your system is 32 bits system). otherwise you will get undefined behaviour
No, you're actually removing bits 0 to 15 from p, so it will hold 0xdead and afterwards you perform the bitwise and so this will yield 0.
If you want to extract the upper 16 bits you will first have to the & operation and shift afterwards:
p = (p & 0xffff0000) >> 16;
To extracts the bits 4 to 7 you will want to do:
p = p & 0xf0;
or if you want them shifted down
p = (p & 0xf0) >> 4;
Btw. Could it be that mean the term nibble 4 to 7 instead of bit 4..7? Nibbles are 4 bits and represented by one hex digit, this would correlate with what you are trying to in the code

Left shift using bitwise AND

The following lines of code Shift left 5 bits ie make bottom 3 bits the 3 MSB's
DWORD dwControlLocAddress2;
DWORD dwWriteDataWordAddress //Assume some initial value
dwControlLocAddress2 = ((dwWriteDataWordAddress & '\x07') * 32);
Can somebody help me understand how?
The 0x07 is 00000111 in binary. So you are masking the input value and getting just the right three bits. Then you are multiplying by 32 which is 2 * 2 * 2 * 2 * 2... which, if you think about it, shifting left by 1 is the same as multiplying by 2. So, shifting left five times is the same as multiplying by 32.
Multiplying by a power of two x is the same as left shifting by log2(x):
x *= 2 -> x <<= 1
x *= 4 -> x <<= 2
.
.
.
x *= 32 -> x <<= 5
The & doesn't do the shift - it just masks the bottom three bits. The syntax used in your example is a bit weird - it's using a hexadecimal character literal '\x07', but that's literally identical to hex 0x07, which in turn in binary is:
00000111
Since any bit ANDed with 0 yields 0 and any bit ANDed with 1 is itself, the & operation in your example simply gives a result of being the bottom three bits of dwWriteDataWordAddress.
It's a bit obtuse but essentially you're anding with 0x07 and then multiplying by 32 which is the same as shifting by 5. I'm not sure why a character literal is used rather than an integer literal but perhaps so that it is represented as a single byte rather than a word.
The equivalent would be:
( ( dw & 0x07 ) << 5 )
The & 0x07 masks off the first 3 bits and << 5 does a left shift by 5 bits.
& '\x07' - masks in the bottom three bits only (hex 7 is 111 in binary)
* 32 - left shifts by 5 (32 is 2^5)

how to find left most 1 in a 32bit int in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find the highest order bit in C
How can I write a C function that will generate a mask indicating the leftmost 1 in x.
Ex: 0xFF00 -> 0x8000, and 0x6600 -> 0x4000. So far:
int left1(unsigned x){}
I understand, 0xFF00 == 1111 1111 0000 0000..
and 0x6600 == 0110 0110 0000 0000.. but I'm stumped after that.
You can do this in two parts: first, use a technique called "bit smearing" to ensure that all the bits to the right of the first 1 are also 1:
x |= x >> 16;
x |= x >> 8;
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
At this point, an input of 0xFF00 will leave x equal to 0xFFFF, and an input of 0x6600 will leave x equal to 0x7FFF. We can then leave just the highest 1 set using:
x ^= x >> 1;
Count the number of times it takes to bit-shift to the right until you reach 1, then bit-shift that 1 to the left by that same count.
int ct=0;
while (x > 1) { ct++; x = x >> 1; }
x = x << ct;
One approach is to create a bitmask, and then right-shift the value.
That is, create a bitmask so that your integer is '1000....' or '0.....' - depending on whether that first bit is a 0 or a 1.
Then take that integer and right-shift it until it becomes the least-significant-bit, rather than the most-significant. As an example, 0b10000000 >> 8 is 1.
So first, depending on the size of your integer, you have to shift, well, however many bits are relevant.
Then you have to create the bitmask. Let's just take a 1-byte integer:
unsigned int i = 1 << 8 would create an integer i whose most significant bit is a 1.
Or you could use hex. You already know that 0xFF == 11111111. You can actually break it up further: 0xF0 == 11110000
Since 0xF == 1111 in binary, well, we will do the reverse. 1000 in binary is what, in hex? 1000 in binary is the number 8, which also happens to equal 0x8
So, for a single byte, the mask for the leftmost bit is 0x80.
Now! Apply this to 32 bits!
Good luck!

Resources