C - Swap a bit between two numbers - c

I just tried with this code:
void swapBit(unsigned char* numbA, unsigned char* numbB, short bitPosition)//bitPosition 0-x
{
unsigned char oneShift = 1 << bitPosition;
unsigned char bitA = *numbA & oneShift;
unsigned char bitB = *numbB & oneShift;
if (bitA)
*numbB |= bitA;
else
*numbB &= (~bitA ^ oneShift);
if (bitB)
*numbA |= bitB;
else
*numbA &= (~bitB ^ oneShift);
}
to swap bit position x of a and b but because of the if() I think there's something better.
Also when i see this:
*numbB &= (~bitA ^ oneShift);
I really think that there's an easier way to do it.
If you have something for me, i would take it :)
Thanks in advance

First you should set the corresponding position in a number to 0, and then OR it with the actual bit, removing all of the conditions:
*numbB &= ~oneShift; // Set the bit to `0`
*numbB |= bitA; // Set to the actual bit value
The same for the other number.

A single bit is no easier than an arbitrary bitmask, so lets just talk about that. You can always call this function with 1U << bitpos.
If a bit position is the same in both values, no change is needed in either. If it's opposite, they both need to invert.
XOR with 1 flips a bit; XOR with 0 is a no-op.
So what we want is a value that has a 1 everywhere there's a bit-difference between the inputs, and a 0 everywhere else. That's exactly what a XOR b does. Simply mask this to only swap some of the bits, and we have a bit-swap in 3 XORs + 1 AND.
// call with unsigned char mask = 1U << bitPosition; if you want
inline
void swapBit_char(unsigned char *A, unsigned char *B, unsigned char mask)
{
unsigned char tmpA = *A, tmpB = *B; // read into locals in case A==B
unsigned char bitdiff = tmpA ^ tmpB;
bitdiff &= mask; // only swap bits matching the mask
*A = tmpA ^ bitdiff;
*B = tmpB ^ bitdiff;
}
(Godbolt compiler explorer with gcc for x86-64 and ARM, includes a version with unsigned instead of unsigned char.)
You could consider if(bitdiff) { ... }, but unless you're going to avoid dirtying a cache line in memory by avoiding the assignments, it's probably not worth doing any conditional behaviour. With values in registers (after inlining), a branch to save two xor instructions is almost never worth it.
This is not an xor-swap. It does use temporary storage. As #chux's answer demonstrates, a masked xor-swap requires 3 AND operations as well as 3 XOR. (And defeats the only benefit of XOR-swap by requiring a temporary register or other storage for the & results.)
This version only requires 1 AND. Also, the last two XORs are independent of each other, so total latency from inputs to both outputs is only 3 operations. (Typically 3 cycles).
For an x86 asm example, see this code-golf Exchange capitalization of two strings in 14 bytes of x86-64 machine code (with commented asm source)

Form the mask
unsigned char mask = 1u << bitPosition;
And then earn the wrath of your peer group with XOR swap algorithm.
*numbA ^= *numbB & mask;
*numbB ^= *numbA & mask;
*numbA ^= *numbB & mask;
Note this fails when numbA == numbB.

Related

Testing values with & 1<<0?

I am new when it comes to bit-wise operations and I stumbled across something interesting. Assume the following:
unsigned char A;
unsigned char B;
if(A & 1 << 0){
//testing
}
Why is it always required to have variable & 1<<0?
Is there a case when this is not required?
Suppose we have:
unsigned char temp;
temp = ~A & ~B;
and we are looking to test out temp. What is the difference when testing temp by itself vs testing only bit 0 with temp & 1<<0?
Thanks!
1<<0 is pointless, shifting 1 left zero bits has no effect.
1<<0 == 1
The below would work identical
unsigned char A;
unsigned char B;
if(A & 1){
//testing
}
It's the single & that makes this a bit-wise operation, not the shift left (<<) operation
If you wanted to test bit 7 for example, you could go about it two ways:
if (A & 128) {
or
if (A & (1<<7)) {
In the case of the latter since it's using constant values the compiler would simply distil this down to 128 and avoid the shl entirely, so it's entirely up to you which you would like to use depending on the code and your coding style.

Getting four bits from the right only in a byte using bit shift operations

I wanted to try to get only the four bits from the right in a byte by using only bit shift operations but it sometimes worked and sometimes not, but I don't understand why.
Here's an example:
unsigned char b = foo; //say foo is 1000 1010
unsigned char temp=0u;
temp |= ((b << 4) >> 4);//I want this to be 00001010
PS: I know I can use a mask=F and do temp =(mask&=b).
Shift operator only only works on integral types. Using << causes implicit integral promotion, type casting b to an int and "protecting" the higher bits.
To solve, use temp = ((unsigned char)(b << 4)) >> 4;

Manipulating bits in C. Is there a better way?

I have a program that uses the following two functions 99.9999% of time:
unsigned int getBit(unsigned char *byte, unsigned int bitPosition)
{
return (*byte & (1 << bitPosition)) >> bitPosition;
}
void setBit(unsigned char *byte, unsigned int bitPosition, unsigned int bitValue)
{
*byte = (*byte | (1 << bitPosition)) ^ ((bitValue ^ 1) << bitPosition);
}
Can this be improved? The processing speed of the program mainly depends on the speed of these two functions.
UPDATE
I will do a benchmark for each provided answer bellow and write the timings I get. For the reference, the compiler used is gcc on Mac OS X platform:
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
I compile without any specific arguments like: gcc -o program program.c
If you think I should set some optimizations, feel free to suggest.
The CPU is:
2,53 GHz Intel Core 2 Duo
While processing 21.5 MB of data with my originally provided functions it takes about:
Time: 13.565221
Time: 13.558416
Time: 13.566042
Time is in seconds (these are three tries).
-- UPDATE 2 --
I've used the -O3 optimization (gcc -O3 -o program program.c) option and now I'm getting these results:
Time: 6.168574
Time: 6.170481
Time: 6.167839
I'll redo the other benchmarks now...
If you want to stick with functions, then for the first one:
unsigned int getBit(unsigned char *byte, unsigned int bitPosition)
{
return (*byte >> bitPosition) & 1;
}
For the second one:
void setBit(unsigned char *byte, unsigned int bitPosition, unsigned int bitValue)
{
if(bitValue == 0)
*byte &= ~(1 << bitPosition);
else
*byte |= (1 << bitPosition);
}
However, I suspect that the function call/return overhead will swamp the actual bit-flipping. A good compiler might inline these function calls anyways, but you may get some improvement by defining these as macros:
#define getBit(b, p) ((*(b) >> (p)) & 1)
#define setBit(b, p, v) (*(b) = ((v) ? (*(b) | (1 << (p))) : (*(b) & (~(1 << (p))))))
#user694733 pointed out that branch prediction might be a problem and could cause a slowdown. As such it might be good to define separate setBit and clearBit functions:
void setBit(unsigned char *byte, unsigned int bitPosition)
(
*byte |= (1 << bitPosition);
}
void clearBit(unsigned char *byte, unsigned int bitPosition)
(
*byte &= ~(1 << bitPosition);
}
And their corresponding macro versions:
#define setBit(b, p) (*(b) |= (1 << (p)))
#define clearBit(b, p) (*(b) &= ~(1 << (p)))
The separate functions/macros would be useful if the calling code hard-codes the value passed for the bitValue argument in the original version.
Share and enjoy.
How about:
bool getBit(unsigned char byte, unsigned int bitPosition)
{
return (byte & (1 << bitPosition)) != 0;
}
No need to use a shift operator to "physically" shift the masked-out bit into position 0, just use a comparison operator and let the compiler deal with it. This should of course also be made inline if possible.
For the second one, it's complicated by the fact that it's basically "assignBit", i.e. it takes the new value of the indicated bit as a parameter. I'd try using the explicit branch:
unsigned char setBit(unsigned char byte, unsigned int bitPosition, bool value)
{
const uint8_t mask = 1 << bitPosition;
if(value)
return byte | mask;
return byte & ~mask;
}
Generally, these things are best left to the compiler's optimizer.
But why do you need functions for such trivial tasks? A C programmer should not get shocked when they encounter basic stuff like this:
x |= 1<<n; // set bit
x &= ~(1<<n); // clear bit
x ^= 1<<n; // toggle bit
y = x & (1<<n); // read bit
There is no real reason to hide simple things like these behind functions. You won't make the code more readable, because you can always assume that the reader of your code knows C. It rather seems like pointless wrapper functions to hide away "scary" operators that the programmer isn't familiar with.
That being said, the introduction of the functions may cause a lot of overhead code. To turn your functions back into the core operations shown above, the optimizer would have to be quite good.
If you for some reason persists in using the functions, any attempt of manual optimization is going to be questionable practice. The use of inline, register and such keywords are likely superfluous. The compiler with optimizer enabled should be far more capable to make the decision when to inline and when to put things in registers than the programmer.
As usual, it doesn't make sense to manually optimize code, unless you know more about the given CPU than the person who wrote the compiler port for it. Most often this is not the case.
What you can harmlessly do as manual optimization, is to get rid of unsigned char (you shouldn't be using the native C types for this anyhow). Instead use the uint_fast8_t type from stdint.h. Using this type means: "I would like to have an uint8_t, but if the CPU prefers a larger type for alignment/performance reasons, it can use that instead".
EDIT
There are different ways to set a bit to either 1 or 0. For maximum readability, you would write this:
uint8_t val = either_1_or_0;
...
if(val == 1)
byte |= 1<<n;
else
byte &= ~(1<<n);
This does however include a branch. Let's assume we know that the branch is a known performance bottleneck on the given system, to justify the otherwise questionable practice of manual optimization. We could then set the bit to either 1 or 0 without a branch, in the following manner:
byte = (byte & ~(1<<n)) | (val<<n);
And this is where the code is turning a bit unreadable. Read the above as:
Take the byte and preserve everything in it, except for the bit we want to set to 1 or 0.
Clear this bit.
Then set it to either 1 or 0.
Note that the whole right side sub-expression is pointless if val is zero. So on a "generic system" this code is possibly slower than the readable version. So before writing code like this, we would have to know that our CPU is very good at bit-flipping and not-so-good at branch prediction.
You can benchmark with the following variations and keep the best of all solutions.
inline unsigned int getBit(unsigned char *byte, unsigned int bitPosition)
{
const unsigned char mask = (unsigned char)(1U << bitPosition);
return !!(*byte & mask);
}
inline void setBit(unsigned char *byte, unsigned int bitPosition, unsigned int bitValue)
{
const unsigned char mask = (unsigned char)(1U << bitPosition);
bitValue ? *byte |= mask : *byte &= ~mask;
}
If your algorithm expects only zero v/s non zero result from getBit, you can remove !! from return. (To return 0 or 1, I found the version of #BobJarvis really clean)
If your algorithm can pass the bit mask to be set or reset to setBit function, you won't need to calculate mask explicitly.
So depending on the code calling these functions, it may be possible to cut on time.

Introducing errors by flipping bits

I have a character array in C into which I want to introduce errors by flipping some bits.
How can I flip bits and introduce errors?
You can flip bits using the xor operator:
x = x ^ mask;
x ^= mask; // Same functionality as above.
For example, if mask is 1, the least significant bit is flipped. You can create any desired mask by bit-shifting the 1: mask = 1 << k; where k is the number of bits to shift.
For distributing the errors, use a random number generator. rand() / srand() should suffice if this is for test purposes.
To flip a bit you can use the bit shifting and bitwise xor operators.
unsigned char flip(unsigned char c, int bit) {
return c ^ (1 << bit);
}
You can also flip more than one bit by using a bitmask other than (1 << bit), which has just one bit set:
unsigned char flip(unsigned char c, unsigned char mask) {
return c ^ (1 << mask);
}
// flip bits 0 and 3 (00001001 = 0x09)
flip(c, 0x09);

bitwise indexing in C?

I'm trying to implement a data compression idea I've had, and since I'm imagining running it against a large corpus of test data, I had thought to code it in C (I mostly have experience in scripting languages like Ruby and Tcl.)
Looking through the O'Reilly 'cow' books on C, I realize that I can't simply index the bits of a simple 'char' or 'int' type variable as I'd like to to do bitwise comparisons and operators.
Am I correct in this perception? Is it reasonable for me to use an enumerated type for representing a bit (and make an array of these, and writing functions to convert to and from char)? If so, is such a type and functions defined in a standard library already somewhere? Are there other (better?) approaches? Is there some example code somewhere that someone could point me to?
Thanks -
Following on from what Kyle has said, you can use a macro to do the hard work for you.
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 6th-from
right
To clear a bit, use AND:
x &= ~(1 << 5); // clears
6th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 6th-from-right
Or...
#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set
#define SetBit(var, bit) (var |= (1 << bit))
#define FlipBit(var, bit) (var ^= (1 << bit))
Then you can use it in code like:
int myVar = 0;
SetBit(myVar, 5);
if (GetBit(myVar, 5))
{
// Do something
}
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 5th-from right
To clear a bit, use AND:
x &= ~(1 << 5); // clears 5th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 5th-from-right
To get the value of a bit use shift and AND:
(x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right
note: the shift right 5 is to ensure the value is either 0 or 1. If you're just interested in 0/not 0, you can get by without the shift.
Have a look at the answers to this question.
Theory
There is no C syntax for accessing or setting the n-th bit of a built-in datatype (e.g. a 'char'). However, you can access bits using a logical AND operation, and set bits using a logical OR operation.
As an example, say that you have a variable that holds 1101 and you want to check the 2nd bit from the left. Simply perform a logical AND with 0100:
1101
0100
---- AND
0100
If the result is non-zero, then the 2nd bit must have been set; otherwise is was not set.
If you want to set the 3rd bit from the left, then perform a logical OR with 0010:
1101
0010
---- OR
1111
You can use the C operators && (for AND) and || (for OR) to perform these tasks. You will need to construct the bit access patterns (the 0100 and 0010 in the above examples) yourself. The trick is to remember that the least significant bit (LSB) counts 1s, the next LSB counts 2s, then 4s etc. So, the bit access pattern for the n-th LSB (starting at 0) is simply the value of 2^n. The easiest way to compute this in C is to shift the binary value 0001 (in this four bit example) to the left by the required number of places. As this value is always equal to 1 in unsigned integer-like quantities, this is just '1 << n'
Example
unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */
/* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */
unsigned char pattern = 1;
pattern <<= 3; /* Shift pattern left by three places.*/
if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */
/* Set the most significant bit. */
myVal |= (char)(1<<7);
This example hasn't been tested, but should serve to illustrate the general idea.
To query state of bit with specific index:
int index_state = variable & ( 1 << bit_index );
To set bit:
varabile |= 1 << bit_index;
To restart bit:
variable &= ~( 1 << bit_index );
Try using bitfields. Be careful the implementation can vary by compiler.
http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html
IF you want to index a bit you could:
bit = (char & 0xF0) >> 7;
gets the msb of a char. You could even leave out the right shift and do a test on 0.
bit = char & 0xF0;
if the bit is set the result will be > 0;
obviousuly, you need to change the mask to get different bits (NB: the 0xF is the bit mask if it is unclear). It is possible to define numerous masks e.g.
#define BIT_0 0x1 // or 1 << 0
#define BIT_1 0x2 // or 1 << 1
#define BIT_2 0x4 // or 1 << 2
#define BIT_3 0x8 // or 1 << 3
etc...
This gives you:
bit = char & BIT_1;
You can use these definitions in the above code to sucessfully index a bit within either a macro or a function.
To set a bit:
char |= BIT_2;
To clear a bit:
char &= ~BIT_3
To toggle a bit
char ^= BIT_4
This help?
Individual bits can be indexed as follows.
Define a struct like this one:
struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned reserved : 28;
} bitPattern;
Now if I want to know the individual bit values of a var named "value", do the following:
CopyMemory( &input, &value, sizeof(value) );
To see if bit 2 is high or low:
int state = bitPattern.bit2;
Hope this helps.
There is a standard library container for bits: std::vector. It is specialised in the library to be space efficient. There is also a boost dynamic_bitset class.
These will let you perform operations on a set of boolean values, using one bit per value of underlying storage.
Boost dynamic bitset documentation
For the STL documentation, see your compiler documentation.
Of course, you can also address the individual bits in other integral types by hand. If you do that, you should use unsigned types so that you don't get undefined behaviour if decide to do a right shift on a value with the high bit set. However, it sounds like you want the containers.
To the commenter who claimed this takes 32x more space than necessary: boost::dynamic_bitset and vector are specialised to use one bit per entry, and so there is not a space penalty, assuming that you actually want more than the number of bits in a primitive type. These classes allow you to address individual bits in a large container with efficient underlying storage. If you just want (say) 32 bits, by all means, use an int. If you want some large number of bits, you can use a library container.

Resources