Setting invidual bits in byte by group of bits - c

For example:
We have a byte A: XXXX XXXX
We have a byte B: 0000 0110
And now for example we want 4 bits from byte B on specific position and we want to put inside byte A on specific position like so we have a result:
We have a byte A: 0110 XXXX
Im still searching through magic functions without success.
Found similar and reworking it but still have no endgame with it:
unsigned int i, j; // positions of bit sequences to swap
unsigned int n; // number of consecutive bits in each sequence
unsigned int b; // bits to swap reside in b
unsigned int r; // bit-swapped result goes here
unsigned int x = ((b >> i) ^ (b >> j)) & ((1U << n) - 1); // XOR temporary
r = b ^ ((x << i) | (x << j));
As an example of swapping ranges of bits suppose we have have b = 00101111 (expressed in binary) and we want to swap the n = 3 consecutive bits starting at i = 1 (the second bit from the right) with the 3 consecutive bits starting at j = 5; the result would be r = 11100011 (binary).
This method of swapping is similar to the general purpose XOR swap trick, but intended for operating on individual bits. The variable x stores the result of XORing the pairs of bit values we want to swap, and then the bits are set to the result of themselves XORed with x. Of course, the result is undefined if the sequences overlap.

It's hard to understand your requirenments exactly, so correct me if I'm wrong:
You want to take the last 4 bits of a byte (B) and add them to the first for bits of byte A? You use the term 'put inside' but it's unclear what you mean exactly by it (If not adding, do you mean replace?).
So assuming addition is what you want you could do something like this:
A = A | (B <<4)
This will shift by 4 bits to the left (thereby ending up with 01100000) and then 'adding ' it to A (using or).

byte A: YYYY XXXX
byte B: 0000 0110
and you want 0110 XXXX
so AND A with 00001111 then copy the last 4 bits of B (first shift then OR)
a &= 0x0F; //now a is XXXX
a |= (b << 4); //shift B to 01100000 then OR to get your result
if you wanted 0110 YYYY just shift a by 4 to the right instead of AND
a >>= 4

Found an solution :
x = ((b>>i)^(r>>j)) & ((1U << n) -1)
r = r^(x << j)
where r is the 2nd BYTE, i,j are indexes in order (from,to).

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 do I extract bits from 32 bit number

I have do not have much knowledge of C and I'm stuck with a problem since one of my colleague is on leave.
I have a 32 bit number and i have to extract bits from it. I did go through a few threads but I'm still not clear how to do so. I would be highly obliged if someone can help me.
Here is an example of what I need to do:
Assume hex number = 0xD7448EAB.
In binary = 1101 0111 0100 0100 1000 1110 1010 1011.
I need to extract the 16 bits, and output that value. I want bits 10 through 25.
The lower 10 bits (Decimal) are ignored. i.e., 10 1010 1011 are ignored.
And the upper 6 bits (Overflow) are ignored. i.e. 1101 01 are ignored.
The remaining 16 bits of data needs to be the output which is 11 0100 0100 1000 11 (numbers in italics are needed as the output).
This was an example but I will keep getting different hex numbers all the time and I need to extract the same bits as I explained.
How do I solve this?
Thank you.
For this example you would output 1101 0001 0010 0011, which is 0xD123, or 53,539 decimal.
You need masks to get the bits you want. Masks are numbers that you can use to sift through bits in the manner you want (keep bits, delete/clear bits, modify numbers etc). What you need to know are the AND, OR, XOR, NOT, and shifting operations. For what you need, you'll only need a couple.
You know shifting: x << y moves bits from x *y positions to the left*.
How to get x bits set to 1 in order: (1 << x) - 1
How to get x bits set to 1, in order, starting from y to y + x: ((1 << x) -1) << y
The above is your mask for the bits you need. So for example if you want 16 bits of 0xD7448EAB, from 10 to 25, you'll need the above, for x = 16 and y = 10.
And now to get the bits you want, just AND your number 0xD7448EAB with the mask above and you'll get the masked 0xD7448EAB with only the bits you want. Later, if you want to go through each one, you'll need to shift your result by 10 to the right and process each bit at a time (at position 0).
The answer may be a bit longer, but it's better design than just hard coding with 0xff or whatever.
OK, here's how I wrote it:
#include <stdint.h>
#include <stdio.h>
main() {
uint32_t in = 0xd7448eab;
uint16_t out = 0;
out = in >> 10; // Shift right 10 bits
out &= 0xffff; // Only lower 16 bits
printf("%x\n",out);
}
The in >> 10 shifts the number right 10 bits; the & 0xffff discards all bits except the lower 16 bits.
I want bits 10 through 25.
You can do this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number & 0x3FFFC00) >> 10;
Or this:
unsigned int number = 0xD7448EAB;
unsigned int value = (number >> 10) & 0xFFFF;
I combined the top 2 answers above to write a C program that extracts the bits for any range of bits (not just 10 through 25) of a 32-bit unsigned int. The way the function works is that it returns bits lo to hi (inclusive) of num.
#include <stdio.h>
#include <stdint.h>
unsigned extract(unsigned num, unsigned hi, unsigned lo) {
uint32_t range = (hi - lo + 1); //number of bits to be extracted
//shifting a number by the number of bits it has produces inconsistent
//results across machines so we need a special case for extract(num, 31, 0)
if(range == 32)
return num;
uint32_t result = 0;
//following the rule above, ((1 << x) - 1) << y) makes the mask:
uint32_t mask = ((1 << range) -1) << lo;
//AND num and mask to get only the bits in our range
result = num & mask;
result = result >> lo; //gets rid of trailing 0s
return result;
}
int main() {
unsigned int num = 0xd7448eab;
printf("0x%x\n", extract(num, 10, 25));
}

How do I perform a circular rotation of a byte?

I'm trying to implement a function that performs a circular rotation of a byte to the left and to the right.
I wrote the same code for both operations. For example, if you are rotating left 1010 becomes 0101. Is this right?
unsigned char rotl(unsigned char c) {
int w;
unsigned char s = c;
for (w = 7; w >= 0; w--) {
int b = (int)getBit(c, w);//
if (b == 0) {
s = clearBit(s, 7 - w);
} else if (b == 1) {
s = setBit(s, 7 - w);
}
}
return s;
}
unsigned char getBit(unsigned char c, int n) {
return c = (c & (1 << n)) >> n;
}
unsigned char setBit(unsigned char c, int n) {
return c = c | (1 << n);
}
unsigned char clearBit(unsigned char c, int n) {
return c = c &(~(1 << n));
}
There is no rotation operator in C, but if you write:
unsigned char rotl(unsigned char c)
{
return (c << 1) | (c >> 7);
}
then, according to this: http://www.linux-kongress.org/2009/slides/compiler_survey_felix_von_leitner.pdf (page 56), compilers will figure out what you want to do and perform the rotation it in only one (very fast) instruction.
Reading the answers and comments so far, there seems to be some confusion about what you are trying to accomplish - this may be because of the words you use. In bit manipulation, there are several "standard" things you can do. I will summarize some of these to help clarify different concepts. In all that follows, I will use abcdefgh to denote 8 bits (could be ones or zeros) - and as they move around, the same letter will refer to the same bit (maybe in a different position); if a bit becomes "definitely 0 or 1, I will denote it as such).
1) Bit shifting: This is essentially a "fast multiply or divide by a power of 2". The symbol used is << for "left shift" (multiply) or >> for right shift (divide). Thus
abcdefgh >> 2 = 00abcdef
(equivalent to "divide by four") and
abcdefgh << 3 = abcdefgh000
(equivalent to "multiply by eight" - and assuming there was "space" to shift the abc into; otherwise this might result in an overflow)
2) Bit masking: sometimes you want to set certain bits to zero. You do this by doing an AND operation with a number that has ones where you want to preserve a bit, and zeros where you want to clear a bit.
abcdefgh & 01011010 = 0b0de0g0
Or if you want to make sure certain bits are one, you use the OR operation:
abcdefgh | 01011010 = a1c11f1h
3) Circular shift: this is a bit trickier - there are instances where you want to "move bits around", with the ones that "fall off at one end" re-appearing at the other end. There is no symbol for this in C, and no "quick instruction" (although most processors have a built-in instruction which assembler code can take advantage of for FFT calculations and such). If you want to do a "left circular shift" by three positions:
circshift(abcdefgh, 3) = defghabc
(note: there is no circshift function in the standard C libraries, although it exists in other languages - e.g. Matlab). By the same token a "right shift" would be
circshift(abcdefgh, -2) = ghabcdef
4) Bit reversal: Sometimes you need to reverse the bits in a number. When reversing the bits, there is no "left" or "right" - reversed is reversed:
reverse(abcdefgh) = hgfedcba
Again, there isn't actually a "reverse" function in standard C libraries.
Now, let's take a look at some tricks for implementing these last two functions (circshift and reverse) in C. There are entire websites devoted to "clever ways to manipulate bits" - see for example this excellent one. for a wonderful collection of "bit hacks", although some of these may be a little advanced...
unsigned char circshift(unsigned char x, int n) {
return (x << n) | (x >> (8 - n));
}
This uses two tricks from the above: shifting bits, and using the OR operation to set bits to specific values. Let's look at how it works, for n = 3 (note - I am ignoring bits above the 8th bit since the return type of the function is unsigned char):
(abcdefgh << 3) = defgh000
(abcdefgh >> (8 - 3)) = 00000abc
Taking the bitwise OR of these two gives
defgh000 | 00000abc = defghabc
Which is exactly the result we wanted. Note also that a << n is the same as a >> (-n); in other words, right shifting by a negative number is the same as left shifting by a positive number, and vice versa.
Now let's look at the reverse function. There are "fast ways" and "slow ways" to do this. Your code above gave a "very slow" way - let me show you a "very fast" way, assuming that your compiler allows the use of 64 bit (long long) integers.
unsigned char reverse(unsigned char b) {
return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
}
You may ask yourself "what just happened"??? Let me show you:
b = abcdefgh
* 0x0000000202020202 = 00000000 00000000 0000000a bcdefgha bcdefgha bcdefgha bcdefgha bcdefgh0
& 0x0000010884422010 = 00000000 00000000 00000001 00001000 10000100 01000010 00100000 00010000
= 00000000 00000000 0000000a 0000f000 b0000g00 0c0000h0 00d00000 000e0000
Note that we now have all the bits exactly once - they are just in a rather strange pattern. The modulo 1023 division "collapses" the bits of interest on top of each other - it's like magic, and I can't explain it. The result is indeed
hgfedcba
A slightly less obscure way to achieve the same thing (less efficient, but works for larger numbers quite efficiently) recognizes that if you swap adjacent bits , then adjacent bit pairs, then adjacent nibbles (4 bit groups), etc - you end up with a complete bit reversal. In that case, a byte reversal becomes
unsigned char bytereverse(unsigned char b) {
b = (b & 0x55) << 1 | (b & 0xAA) >> 1; // swap adjacent bits
b = (b & 0x33) << 2 | (b & 0xCC) >> 2; // swap adjacent pairs
b = (b & 0x0F) << 4 | (b & 0xF0) >> 4; // swap nibbles
return b;
}
In this case the following happens to byte b = abcdefgh:
b & 0x55 = abcdefgh & 01010101 = 0b0d0f0h << 1 = b0d0f0h0
b & 0xAA = abcdefgh & 10101010 = a0c0e0g0 >> 1 = 0a0c0e0g
OR these two to get badcfehg
Next line:
b & 0x33 = badcfehg & 00110011 = 00dc00hg << 2 = dc00hg00
b & 0xCC = badcfehg & 11001100 = ba00fe00 >> 2 = 00ba00fe
OR these to get dcbahgfe
last line:
b & 0x0F = dcbahgfe & 00001111 = 0000hgfe << 4 = hgfe0000
b & 0xF0 = dcbahgfe & 11110000 = dcba0000 >> 4 = 0000dcba
OR these to get hgfedcba
Which is the reversed byte you were after. It should be easy to see how just a couple more lines (similar to the above) get you to a reversed integer (32 bits). As the size of the number increases, this trick becomes more and more efficient, comparatively.
I trust that the answer you were looking for is "somewhere" in the above. If nothing else I hope you have a clearer understanding of the possibilities of bit manipulation in C.
If, as according to your comments, you want to shift one bit exactly, then one easy way to accomplish that would be this:
unsigned char rotl(unsigned char c)
{
return((c << 1) | (c >> 7));
}
What your code does is reversing the bits; not rotating them. For instance, it would make 10111001 into 10011101, not 01110011.

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!

Swap two bits with a single operation in C?

Let's say I have a byte with six unknown values:
???1?0??
and I want to swap bits 2 and 4 (without changing any of the ? values):
???0?1??
But how would I do this in one operation in C?
I'm performing this operation thousands of times per second on a microcontroller so performance is the top priority.
It would be fine to "toggle" these bits. Even though this is not the same as swapping the bits, toggling would work fine for my purposes.
Try:
x ^= 0x14;
That toggles both bits. It's a little bit unclear in question as you first mention swap and then give a toggle example. Anyway, to swap the bits:
x = precomputed_lookup [x];
where precomputed_lookup is a 256 byte array, could be the fastest way, it depends on the memory speed relative to the processor speed. Otherwise, it's:
x = (x & ~0x14) | ((x & 0x10) >> 2) | ((x & 0x04) << 2);
EDIT: Some more information about toggling bits.
When you xor (^) two integer values together, the xor is performed at the bit level, like this:
for each (bit in value 1 and value 2)
result bit = value 1 bit xor value 2 bit
so that bit 0 of the first value is xor'ed with bit 0 of the second value, bit 1 with bit 1 and so on. The xor operation doesn't affect the other bits in the value. In effect, it's a parallel bit xor on many bits.
Looking at the truth table for xor, you will see that xor'ing a bit with the value '1' effectively toggles the bit.
a b a^b
0 0 0
0 1 1
1 0 1
1 1 0
So, to toggle bits 1 and 3, write a binary number with a one where you want the bit to toggle and a zero where you want to leave the value unchanged:
00001010
convert to hex: 0x0a. You can toggle as many bits as you want:
0x39 = 00111001
will toggle bits 0, 3, 4 and 5
You cannot "swap" two bits (i.e. the bits change places, not value) in a single instruction using bit-fiddling.
The optimum approach if you want to really swap them is probably a lookup table. This holds true for many 'awkward' transformations.
BYTE lookup[256] = {/* left this to your imagination */};
for (/*all my data values */)
newValue = lookup[oldValue];
The following method is NOT a single C instruction, it's just another bit fiddling method. The method was simplified from Swapping individual bits with XOR.
As stated in Roddy's answer, a lookup table would be best. I only suggest this in case you didn't want to use one. This will indeed swap bits also, not just toggle (that is, whatever is in bit 2 will be in 4 and vice versa).
b: your original value - ???1?0?? for instance
x: just a temp
r: the result
x = ((b >> 2) ^ (b >> 4)) & 0x01
r = b ^ ((x << 2) | (x << 4))
Quick explanation: get the two bits you want to look at and XOR them, store the value to x. By shifting this value back to bits 2 and 4 (and OR'ing together) you get a mask that when XORed back with b will swap your two original bits. The table below shows all possible cases.
bit2: 0 1 0 1
bit4: 0 0 1 1
x : 0 1 1 0 <-- Low bit of x only in this case
r2 : 0 0 1 1
r4 : 0 1 0 1
I did not fully test this, but for the few cases I tried quickly it seemed to work.
This might not be optimized, but it should work:
unsigned char bit_swap(unsigned char n, unsigned char pos1, unsigned char pos2)
{
unsigned char mask1 = 0x01 << pos1;
unsigned char mask2 = 0x01 << pos2;
if ( !((n & mask1) != (n & mask2)) )
n ^= (mask1 | mask2);
return n;
}
The function below will swap bits 2 and 4. You can use this to precompute a lookup table, if necessary (so that swapping becomes a single operation):
unsigned char swap24(unsigned char bytein) {
unsigned char mask2 = ( bytein & 0x04 ) << 2;
unsigned char mask4 = ( bytein & 0x10 ) >> 2;
unsigned char mask = mask2 | mask4 ;
return ( bytein & 0xeb ) | mask;
}
I wrote each operation on a separate line to make it clearer.
void swap_bits(uint32_t& n, int a, int b) {
bool r = (n & (1 << a)) != 0;
bool s = (n & (1 << b)) != 0;
if(r != s) {
if(r) {
n |= (1 << b);
n &= ~(1 << a);
}
else {
n &= ~(1 << b);
n |= (1 << a);
}
}
}
n is the integer you want to be swapped in, a and b are the positions (indexes) of the bits you want to be swapped, counting from the less significant bit and starting from zero.
Using your example (n = ???1?0??), you'd call the function as follows:
swap_bits(n, 2, 4);
Rationale: you only need to swap the bits if they are different (that's why r != s). In this case, one of them is 1 and the other is 0. After that, just notice you want to do exactly one bit set operation and one bit clear operation.
Say your value is x i.e, x=???1?0??
The two bits can be toggled by this operation:
x = x ^ ((1<<2) | (1<<4));
#include<stdio.h>
void printb(char x) {
int i;
for(i =7;i>=0;i--)
printf("%d",(1 & (x >> i)));
printf("\n");
}
int swapb(char c, int p, int q) {
if( !((c & (1 << p)) >> p) ^ ((c & (1 << q)) >> q) )
printf("bits are not same will not be swaped\n");
else {
c = c ^ (1 << p);
c = c ^ (1 << q);
}
return c;
}
int main()
{
char c = 10;
printb(c);
c = swapb(c, 3, 1);
printb(c);
return 0;
}

Resources