Swap two bits with a single operation in C? - 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;
}

Related

Turn 0 bits to 1 bits if the bit is between low and high

Full disclosure, this is a homework problem and I do not need exact code. I am tasked with reproducing the following code while only using ~ & + <<.
int result = 0;
int i;
for(i = lowbit; i <= highbit; i++)
result |= 1 << i;
return result;
Where lowbit and highbit are parameters between 0 and 31 inclusive. If lowbit is a larger number than highbit, return 0.
What I have tried so for is the following code
int result = 0;
int negone = ~0x0;
int first = 1 << (lowbit + negone); //the first 1 bit is at the lowbit th location
int last = 1 << (highbit + negone); //the last 1 bit is at the highbit th location
int tick = ~(first + last); //attempting to get all bits in the range of low and highbit.
result = ~(~first & ~tick); //bitwise | without using |
result = ~(~last & ~result);
return result + 1; //the first bit should always be on.
So is there something fundamental I am missing here? In addition to what I have not working this also goes over my limit of 12 operators that I am allowed to use, but I'd like to try and get it working before I even begin to limit the operators.
When I run the test script on this I get errors on most of the tests it is put against including lowbit and highbit being equal to each other. Cases where highbit is the max size and lowbit is the least size seem to work though.
Any help would be much appreciated.
negone should be initialized this way:
uint32_t negone = ~0UL;
You are adding the bit number with a bit pattern in:
int first = 1 << (lowbit + negone); //the first 1 bit is at the lowbit th location
int last = 1 << (highbit + negone);
You should instead compute the 32 bit masks
uint32_t first = negone << lowbit; // all bits below lowbit are 0, others are 1
uint32_t last = negone << highbit << 1; // all bits above highbit are 1, other are 0
The result is obtained by masking the complement of first with last:
uint32_t result = ~first & last;
Combining the above steps gives is a direct solution with 7 operators (12 including the parentheses and the assignment), no addition, and no subtraction:
uint32_t result = ~(~0UL << highbit << 1) & (~0UL << lowbit);
I use 0UL because type unsigned long is guaranteed to have at least 32 bits, whereas type unsigned int might have just 16 bits.
1) Create a mask with the bits low to high set:
uint32_t mask = ~(~0ul << highbit << 1) & (~0ul << lowbit)
Example: lowbit = 4, highbit = 12 (9 bits)
mask = ~(0xffffffff << 12 << 1) & (0xffffffff << 4)
= ~(0xffff7000) & 0xfffffff0
= 0x00001fff & 0xfffffff0
= 0x00001ff0
2) Apply the mask to the value to be modified, this most simply an | operation, but that is not a valid operator in this exercise, so must be transformed using De Morgan's forum:
A|B -> ~(~A & ~B) :
result = ~(~result & ~mask) ;
It is of course possible to combining the two steps, but perhaps clarity would not then be served.
The original code generates a block of 1 from lowbit on until highbit (inclusive).
This can be achieved without a loop as follows:
int nrOfBits = highbit + ~lowbit + 2; // highbit - lowbit + 1
int shift = (nrOfBits & 0x1f + 1);
int result = ~(~(1 << shift)+1) << lowbit;
The idea is that, for example a range of 8 bits filled up with 1 means a number of 255, whereas 2^8 is 256. So - as operator - is not allowed, we use 2-complement to get -256, add 1 to get -255, and turn it back to +255 using 2-complement operator ~. Then, we just have to shift the block lowbits left.
The problem could be that tick = ~(first+last) does not flip the bit from the lowbit to the highbit.
Maybe we can do something like this:
/* supposed that lowbit = 1, highbit = 2 */
uint32_t negone = ~(0u); /* negone = all 1s */
uint32_t first = negone << lowbit; /* first = ...111110 */
uint32_t last = (1 << (highbit + 1)) + negone; /* last = ...0000111 */
uint32_t tick = last & first; /* tick = ...000110 */
result = ~(~result&~tick); /* Bitwise Or without | as you mentioned. */
It takes 11 bit operations to do this.
p.s. I am wondering why the first bit should be always on.
Edit: In order to avoid undefined operation, we should use unsigned type, like uint32_t.

Bit wise operators

am having a little trouble with this function of mine. We are supposed to use bit wise operators only (that means no logical operators and no loops or if statements) and we aren't allowed to use a constant bigger than 0xFF.
I got my function to work, but it uses a huge constant. When I try to implement it with smaller numbers and shifting, I can't get it to work and I'm not sure why.
The function is supposed to check all of the even bits in a given integer, and return 1 if they are all set to 1.
Working code
int allEvenBits(int x) {
/* implements a check for all even-numbered bits in the word set to 1 */
/* if yes, the program outputs 1 WORKING */
int all_even_bits = 0x55555555;
return (!((x & all_even_bits) ^ all_even_bits));
}
Trying to implement with a smaller constant and shifts
int allEvenBits(int x) {
/* implements a check for all even-numbered bits in the word set to 1 */
/* if yes, the program outputs 1 WORKING */
int a, b, c, d, e = 0;
int mask = 0x55;
/* first 8 bits */
a = (x & mask)&1;
/* second eight bits */
b = ((x>>8) & mask)&1;
/* third eight bits */
c = ((x>>16) & mask)&1;
/* fourth eight bits */
d = ((x>>24) & mask)&1;
e = a & b & c & d;
return e;
}
What am I doing wrong here?
When you do, for example, this:
d = ((x>>24) & mask)&1;
..you're actually checking whether the lowest bit (with value 1) is set, not whether any of the the mask bits are set... since the &1 at the end bitwise ANDs the result of the rest with 1. If you change the &1 to == mask, you'll instead get 1 when all of the bits set in mask are set in (x>>24), as intended. And of course, the same problem exists for the other similar lines as well.
If you can't use comparisons like == or != either, then you'll need to shift all the interesting bits into the same position, then AND them together and with a mask to eliminate the other bit positions. In two steps, this could be:
/* get bits that are set in every byte of x */
x = (x >> 24) & (x >> 16) & (x >> 8) & x;
/* 1 if all of bits 0, 2, 4 and 6 are set */
return (x >> 6) & (x >> 4) & (x >> 2) & x & 1;
I don't know why you are ANDing your values with 1. What is the purpose of that?
This code is untested, but I would do something along the lines of the following.
int allEvenBits(int x) {
return (x & 0x55 == 0x55) &&
((x >> 8) & 0x55 == 0x55) &&
((x >> 16) & 0x55 == 0x55) &&
((x >> 24) & 0x55 == 0x55);
}
Say you are checking the first 4 least significant digits, the even ones would make 1010. Now you should AND this with the first 4 bits of the number you're checking against. All 1's should remain there. So the test would be ((number & mask) == mask) (mask is 1010) for the 4 least significant bits, you do this in blocks of 4bits (or you can use 8 since you are allowed).
If you aren't allowed to use constants larger than 0xff and your existing program works, how about replacing:
int all_even_bits = 0x55555555;
by:
int all_even_bits = 0x55;
all_even_bits |= all_even_bits << 8; /* it's now 0x5555 */
all_even_bits |= all_even_bits << 16; /* it's now 0x55555555 */
Some of the other answers here right shift signed integers (i.e. int) which is undefined behaviour.
An alternative route is:
int allevenbitsone(unsigned int a)
{
a &= a>>16; /* superimpose top 16 bits on bottom */
a &= a>>8; /* superimpose top 8 bits on bottom */
a &= a>>4; /* superimpose top 4 bits on bottom */
a &= a>>2; /* and down to last 2 bits */
return a&1; /* return & of even bits */
}
What this is doing is and-ing together the even 16 bits into bit 0, and the odd 16 bits into bit 1, then returning bit 0.
the main problem in your code that you're doing &1, so you take first 8 bits from number, mask them with 0x55 and them use only 1st bit, which is wrong
consider straightforward approach:
int evenBitsIn8BitNumber(int a) {
return (a & (a>>2) & (a>>4) & (a>>6)) & 1;
}
int allEvenBits(int a) {
return evenBitsIn8BitNumber(a) &
evenBitsIn8BitNumber(a>>8) &
evenBitsIn8BitNumber(a>>16) &
evenBitsIn8BitNumber(a>>24);
}

How can I check if a value has even parity of bits or odd?

A value has even parity if it has an even number of '1' bits. A value has an odd parity if it has an odd number of '1' bits. For example, 0110 has even parity, and 1110 has odd parity.
I have to return 1 if x has even parity.
int has_even_parity(unsigned int x) {
return
}
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (~x) & 1;
Assuming you know ints are 32 bits.
Let's see how this works. To keep it simple, let's use an 8 bit integer, for which we can skip the first two shift/XORs. Let's label the bits a through h. If we look at our number we see:
( a b c d e f g h )
The first operation is x ^= x >> 4 (remember we're skipping the first two operations since we're only dealing with an 8-bit integer in this example). Let's write the new values of each bit by combining the letters that are XOR'd together (for example, ab means the bit has the value a xor b).
( a b c d e f g h )
xor
( 0 0 0 0 a b c d )
The result is the following bits:
( a b c d ae bf cg dh )
The next operation is x ^= x >> 2:
( a b c d ae bf cg dh )
xor
( 0 0 a b c d ae bf )
The result is the following bits:
( a b ac bd ace bdf aceg bdfh )
Notice how we are beginning to accumulate all the bits on the right-hand side.
The next operation is x ^= x >> 1:
( a b ac bd ace bdf aceg bdfh )
xor
( 0 a b ac bd ace bdf aceg )
The result is the following bits:
( a ab abc abcd abcde abcdef abcdefg abcdefgh )
We have accumulated all the bits in the original word, XOR'd together, in the least-significant bit. So this bit is now zero if and only if there were an even number of 1 bits in the input word (even parity). The same process works on 32-bit integers (but requires those two additional shifts that we skipped in this demonstration).
The final line of code simply strips off all but the least-significant bit (& 1) and then flips it (~x). The result, then, is 1 if the parity of the input word was even, or zero otherwise.
GCC has built-in functions for this:
Built-in Function: int __builtin_parity (unsigned int x)
Returns the parity of x, i.e. the number of 1-bits in x modulo 2.
and similar functions for unsigned long and unsigned long long.
I.e. this function behaves like has_odd_parity. Invert the value for has_even_parity.
These should be the fastest alternative on GCC. Of course its use is not portable as such, but you can use it in your implementation, guarded by a macro for example.
The following answer was unashamedly lifted directly from Bit Twiddling Hacks By Sean Eron Anderson, seander#cs.stanford.edu
Compute parity of word with a multiply
The following method computes the parity of the 32-bit value in only 8 operations >using a multiply.
unsigned int v; // 32-bit word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x11111111U) * 0x11111111U;
return (v >> 28) & 1;
Also for 64-bits, 8 operations are still enough.
unsigned long long v; // 64-bit word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x1111111111111111UL) * 0x1111111111111111UL;
return (v >> 60) & 1;
Andrew Shapira came up with this and sent it to me on Sept. 2, 2007.
Try:
int has_even_parity(unsigned int x){
unsigned int count = 0, i, b = 1;
for(i = 0; i < 32; i++){
if( x & (b << i) ){count++;}
}
if( (count % 2) ){return 0;}
return 1;
}
To generalise TypeIA's answer for any architecture:
int has_even_parity(unsigned int x)
{
unsigned char shift = 1;
while (shift < (sizeof(x)*8))
{
x ^= (x >> shift);
shift <<= 1;
}
return !(x & 0x1);
}
The main idea is this. Unset the rightmost '1' bit by using x & ( x - 1 ). Let’s say x = 13(1101) and the operation of x & ( x - 1 ) is 1101 & 1100 which is 1100, notice that the rightmost set bit is converted to 0.
Now x is 1100. The operation of x & ( x - 1 ), i.e., 1100 & 1011 is 1000. Notice that the original x is 1101 and after two operations of x & (x - 1) the x is 1000, i.e., two set bits are removed after two operations. If after an odd number of operations, the x becomes zero, then it's an odd parity, else it's an even parity.
Here's a one line #define that does the trick for a char:
#define PARITY(x) ((~(x ^= (x ^= (x ^= x >> 4) >> 2) >> 1)) & 1) /* even parity */
int main()
{
char x=3;
printf("parity = %d\n", PARITY(x));
}
It's portable as heck and easily modified to work with bigger words (16, 32 bit). It's important to note also, using a #define speeds the code up, each function call requires time to push the stack and allocate memory. Code size doesn't suffer, especially if it's implemented only a few times in your code - the function call might take up as much object code as the XORs.
Admittedly, the same efficiencies may be obtained by using the inline function version of this, inline char parity(char x) {return PARITY(x);} (GCC) or __inline char parity(char x) {return PARITY(x);} (MSVC). Presuming you keep the one line define.
int parity_check(unsigned x) {
int parity = 0;
while(x != 0) {
parity ^= x;
x >>= 1;
}
return (parity & 0x1);
}
In case the end result is supposed to be a piece of code that can work (be compiled) with a C program then I suggest the following:
.code
; bool CheckParity(size_t Result)
CheckParity PROC
mov rax, 0
add rcx, 0
jnp jmp_over
mov rax, 1
jmp_over:
ret
CheckParity ENDP
END
This is a piece of code I'm using to check the parity of calculated results in a 64-bit C program compiled using MSVC. You can obviously port it to 32 bit or other compilers.
This has the advantage of being much faster than using C and it also leverages the CPU's functionality.
What this example does is take as input a parameter (passed in RCX - __fastcall calling convention). It increments it by 0 thus setting the CPU's parity flag and then setting a variable (RAX) to 0 or 1 if the parity flag is on or not.

Swapping 2 Bytes of Integer

I have a method that receives 3 parameters: int x, int n, and int m. It returns an int with the nth and mth bytes of x swapped
x is just a normal integer, set to any value. n and m are integers between 0 and 3.
For example, let the hex representation of x be 0x12345678, n is 0, and m is 2.
The last and 3rd to last byte are supposed to be switched (n = 78, m = 34).
I have figured out how extract the nth and mth byte from x, but I can't figure out how to recombine all 4 bytes into the integer that the method is supposed to return.
Here is my current code:
`
int byteSwap(int x, int n, int m)
{
// Initialize variables which will hold nth and mth byte
int xn = x;
int xm = x;
// If n is in bytes, n << 3 will be the number of bits in that byte
// For example, if n is 2 (as in 2 bytes), n << 3 will be 16 (as in 16 bits)
xn = x >> (n << 3);
// Mask off everything except the part we want
xn = xn & 0xFF;
// Do the same for m
xm = x >> (m << 3);
xm = xm & 0xFF;
}
`
There are some additional constraints - only the following are allowed:
~ & ^ | ! + << >>
(That means no - * /, loops, ifs, etc. However, additional variables can be initialized and adding is still OK.)
My code can get the nth and mth byte extracted, but I don't get how to recombine everything without using ifs.
Couple of things
You can recombine by masking x with a value that is all FF except for bytes m and n
You can compute the mask by left shifting 0xFF m times and n times and combining the result and then XOR it with 0xFFFFFFFF
int mask = 0;
int mask_m = 0xFF << (m << 3);
int mask_n = 0xFF << (n << 3);
mask = (mask_m | mask_n) ^ 0xFFFFFFFF;
int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
return x_swapped;
FYI when you right shift a signed value, it may or may not propagates 1s instead of 0 into the high order bit and is implementation defined. Either way 0xFF will protect against that.

returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving other bits unchanged

my solution
get the rightmost n bits of y
a = ~(~0 << n) & y
clean the n bits of x beginning from p
c = ( ~0 << p | ~(~0 << (p-n+1))) & x
set the cleaned n bits to the n rightmost bits of y
c | (a << (p-n+1))
it is rather long statements. do we have a better one?
i.e
x = 0 1 1 1 0 1 1 0 1 1 1 0
p = 4
y = 0 1 0 1 1 0 1 0 1 0
n = 3
the 3 rightmost bits of y is 0 1 0
it will replace x from bits 4 to bits 2 which is 1 1 1
I wrote similar one:
unsigned setbits (unsigned x, int p, int n, unsigned y)
{
return (x & ~(~(~0<<n)<<(p+1-n)))|((y & ~(~0<<n))<<(p+1-n));
}
There are two reasonable approaches.
One is yours: Grab the low n bits of y, nuke the middle n bits of x, and "or" them into place.
The other is to build the answer from three parts: Low bits "or" middle bits "or" high bits.
I think I actually like your version better, because I bet n and p are more likely to be compile-time constants than x and y. So your answer becomes two masking operations with constants and one "or"; I doubt you will do better.
I might modify it slightly to make it easier to read:
mask = (~0 << p | ~(~0 << (p-n+1)))
result = (mask & a) | (~mask & (y << (p-n+1)))
...but this is the same speed (indeed, code) as yours when mask is a constant, and quite possibly slower when mask is a variable.
Finally, make sure you have a good reason to worry about this in the first place. Clean code is good, but for something this short, put it in a well-documented function and it does not matter that much. Fast code is good, but do not attempt to micro-optimize something like this until your profiler tells you do. (Modern CPUs do this stuff very fast; it is unlikely your application's performance is bounded by this sort of function. At the very least it is "innocent until proven guilty".)
Have a look at the following descriptive code:
int setbitsKR(int x, int p, int n, int y){
int shiftingDistance = p - n + 1,
bitmask = (1 << n) - 1, // example, 11
digitsOfY = (y & bitmask) << shiftingDistance, // whatever
bitmaskShiftedToLeft = bitmask << shiftingDistance, // 001100
invertedBitmaskShiftedToLeft = ~bitmaskShiftedToLeft; // 110011
// erase those middle bits of x
x &= invertedBitmaskShiftedToLeft;
// add those bits from y into x
x |= digitsOfY;
return x;
}
In short, it creates a bitmask (string of 1s), shifts them to get to that middle position of x, nukes those bits of x by &ing with a string of 0s (inverted bitmask), and finally |s that position with the right digits of y.

Resources