Insert bit into uint16_t - c

Is there any efficient algorithm that allows to insert bit bit to position index when working with uint16_t? I've tried reading bit-by-bit after index, storing all such bits into array of char, changing bit at index, increasing index, and then looping again, inserting bits from array, but could be there a better way? So I know how to get, set, unset or toggle specific bit, but I suppose there could be better algorithm than processing bit-by-bit.
uint16_t bit_insert(uint16_t word, int bit, int index);
bit_insert(0b0000111111111110, 1, 1); /* must return 0b0100011111111111 */
P.S. The solution must be in pure ANSI-compatible C. I know that 0b prefix may be specific to gcc, but I've used it here to make things more obvious.

Use bitwise operators:
#define BIT_INSERT(word, bit, index) \
(((word) & (~(1U << (index)))) | ((bit) << (index)))

#include <errno.h>
#include <stdint.h>
/* Insert a bit `idx' positions from the right (lsb). */
uint16_t
bit_insert_lsb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `idx' inclusive. */
lower = n & ((1U << (idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << idx) | (lower >> 1));
}
/* Insert a bit `idx' positions from the left (msb). */
uint16_t
bit_insert_msb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `16 - idx' inclusive. */
lower = n & ((1U << (15 - idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << (15 - idx)) | (lower >> 1));
}
Bits are typically counted from the right, where the least significant bit (lsb) resides, to the left, where the most significant bit (msb) is located. I allowed for insertion from either side by creating two functions. The one expected, according to the question, is bit_insert_msb.
Both functions perform a sanity check, setting errno to ERANGE and returning 0 if the value of idx is too large. I also provided some of C99's _Bool behaviour for the bit parameter in the return statements: 0 is 0 and any other value is 1. If you use a C99 compiler, I'd recommend changing bit's type to _Bool. You can then replace (!!bit) with bit directly.
I'd love to say it could be optimised, but that could very well make it less comprehensible.
Happy coding!

If you're counting bits from the left
mask = (1 << (16 - index + 1)) - 1; // all 1s from bit "index" to LSB
// MSB of word (from left to index) | insert bit at index | LSB of word from (index-1)
word = (word & ~mask) | (bit << (16 - index)) | ((word & mask) >> 1);
There may be many ways more efficient but this way it's easy to understand

Related

Reverse the order of bits in a bit array

I have a long sequence of bits stored in an array of unsigned long integers, like this
struct bit_array
{
int size; /* nr of bits */
unsigned long *array; /* the container that stores bits */
}
I am trying to design an algorithm to reverse the order of bits in *array. Problems:
size can be anything, i.e. not necessarily a multiple of 8 or 32 etc, so the first bit in the input array can end up at any position within the unsigned long in the output array;
the algorithm should be platform-independent, i.e. work for any sizeof(unsigned long).
Code, pseudocode, algo description etc. -- anything better than bruteforce ("bit by bit") approach is welcome.
My favorite solution is to fill a lookup-table that does bit-reversal on a single byte (hence 256 byte entries).
You apply the table to 1 to 4 bytes of the input operand, with a swap. If the size isn't a multiple of 8, you will need to adjust by a final right shift.
This scales well to larger integers.
Example:
11 10010011 00001010 -> 01010000 11001001 11000000 -> 01 01000011 00100111
To split the number into bytes portably, you need to use bitwise masking/shifts; mapping of a struct or array of bytes onto the integer can make it more efficient.
For brute performance, you can think of mapping up to 16 bits at a time, but this doesn't look quite reasonable.
I like the idea of lookup table. Still it's also a typical task for log(n) group bit tricks that may be very fast. Like:
unsigned long reverseOne(unsigned long x) {
x = ((x & 0xFFFFFFFF00000000) >> 32) | ((x & 0x00000000FFFFFFFF) << 32);
x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
x = ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
x = ((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4);
x = ((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2);
x = ((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1);
return x;
}
The underlying idea is that when we aim to reverse the order of some sequence we may swap the head and tail halves of this sequence and then separately reverse each of halves (which is done here by applying the same procedure recursively to each half).
Here is a more portable version supporting unsigned long widths of 4,8,16 or 32 bytes.
#include <limits.h>
#define ones32 0xFFFFFFFFUL
#if (ULONG_MAX >> 128)
#define fill32(x) (x|(x<<32)|(x<<64)|(x<<96)|(x<<128)|(x<<160)|(x<<192)|(x<<224))
#define patt128 (ones32|(ones32<<32)|(ones32<<64) |(ones32<<96))
#define patt64 (ones32|(ones32<<32)|(ones32<<128)|(ones32<<160))
#define patt32 (ones32|(ones32<<64)|(ones32<<128)|(ones32<<192))
#else
#if (ULONG_MAX >> 64)
#define fill32(x) (x|(x<<32)|(x<<64)|(x<<96))
#define patt64 (ones32|(ones32<<32))
#define patt32 (ones32|(ones32<<64))
#else
#if (ULONG_MAX >> 32)
#define fill32(x) (x|(x<<32))
#define patt32 (ones32)
#else
#define fill32(x) (x)
#endif
#endif
#endif
unsigned long reverseOne(unsigned long x) {
#if (ULONG_MAX >> 32)
#if (ULONG_MAX >> 64)
#if (ULONG_MAX >> 128)
x = ((x & ~patt128) >> 128) | ((x & patt128) << 128);
#endif
x = ((x & ~patt64) >> 64) | ((x & patt64) << 64);
#endif
x = ((x & ~patt32) >> 32) | ((x & patt32) << 32);
#endif
x = ((x & fill32(0xffff0000UL)) >> 16) | ((x & fill32(0x0000ffffUL)) << 16);
x = ((x & fill32(0xff00ff00UL)) >> 8) | ((x & fill32(0x00ff00ffUL)) << 8);
x = ((x & fill32(0xf0f0f0f0UL)) >> 4) | ((x & fill32(0x0f0f0f0fUL)) << 4);
x = ((x & fill32(0xccccccccUL)) >> 2) | ((x & fill32(0x33333333UL)) << 2);
x = ((x & fill32(0xaaaaaaaaUL)) >> 1) | ((x & fill32(0x55555555UL)) << 1);
return x;
}
In a collection of related topics which can be found here, the bits of an individual array entry could be reversed as follows.
unsigned int v; // input bits to be reversed
unsigned int r = v; // r will be reversed bits of v; first get LSB of v
int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
for (v >>= 1; v; v >>= 1)
{
r <<= 1;
r |= v & 1;
s--;
}
r <<= s; // shift when v's highest bits are zero
The reversal of the entire array could be done afterwards by rearranging the individual positions.
You must define what is the order of bits in an unsigned long. You might assume that bit n is corresponds to array[x] & (1 << n) but this needs to be specified. If so, you need to handle the byte ordering (little or big endian) if you are going to use access the array as bytes instead of unsigned long.
I would definitely implement brute force first and measure whether the speed is an issue. No need to waste time trying to optimize this if it is not used a lot on large arrays. An optimized version can be tricky to implement correctly. If you end up trying anyway, the brute force version can be used to verify correctness on test values and benchmark the speed of the optimized version.
The fact that the size is not multiple of sizeof(long) is the hardest part of the problem. This can result in a lot of bit shifting.
But, you don't have to do that if you can introduce new struct member:
struct bit_array
{
int size; /* nr of bits */
int offset; /* First bit position */
unsigned long *array; /* the container that stores bits */
}
Offset would tell you how many bits to ignore at the beginning of the array.
Then you only only have to do following steps:
Reverse array elements.
Swap bits of each element. There are many hacks for in the other answers, but your compiler might also provide intrisic functions to do it in fewer instructions (like RBIT instruction on some ARM cores).
Calculate new starting offset. This is equal to unused bits the last element had.
I would split the problem into two parts.
First, I would ignore the fact that the number of used bits is not a multiple of 32. I would use one of the given methods to swap around the whole array like that.
pseudocode:
for half the longs in the array:
take the first longword;
take the last longword;
swap the bits in the first longword
swap the bits in the last longword;
store the swapped first longword into the last location;
store the swapped last longword into the first location;
and then fix up the fact that the first few bits (call than number n) are actually garbage bits from the end of the longs:
for all of the longs in the array:
split the value in the leftmost n bits and the rest;
store the leftmost n bits into the righthand part of the previous word;
shift the rest bits to the left over n positions (making the rightmost n bits zero);
store them back;
You could try to fold that into one pass over the whole array of course. Something like this:
for half the longs in the array:
take the first longword;
take the last longword;
swap the bits in the first longword
swap the bits in the last longword;
split both value in the leftmost n bits and the rest;
for the new first longword:
store the leftmost n bits into the righthand side of the previous word;
store the remaining bits into the first longword, shifted left;
for the new last longword:
remember the leftmost n bits for the next iteration;
store the remembered leftmost n bits, combined with the remaining bits, into the last longword;
store the swapped first longword into the last location;
store the swapped last longword into the first location;
I'm abstracting from the edge cases here (first and last longword), and you may need to reverse the shifting direction depending on how the bits are ordered inside each longword.

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 to go through each bit of a byte

I do not not know how to implement the following algorithm.
For example I have int=26, this is "11010" in binary.
Now I need to implement one operation for 1, another for 0, from left to right, till the end of byte.
But I really have no idea how to implement this.
Maybe I can convert binary to char array, but I do not know how.
btw, int equals 26 only in the example, in the application it will be random.
Since you want to move from 'left to right':
unsigned char val = 26; // or whatever
unsigned int mask;
for (mask = 0x80; mask != 0; mask >>= 1) {
if (val & mask) {
// bit is 1
}
else {
// bit is 0
}
}
The for loop just walks thorough each bit in a byte, from the most significant bit to the least.
I use this option:
isBitSet = ((bits & 1) == 1);
bits = bits >> 1
I find the answer also in stackoverflow:
How do I properly loop through and print bits of an Int, Long, Float, or BigInteger?
You can use modulo arithmetic or bitmasking to get what you need.
Modulo arithmetic:
int x = 0b100101;
// First bit
(x >> 0) % 2; // 1
// Second bit
(x >> 1) % 2; // 0
// Third bit
(x >> 2) % 2; // 1
...
etc.
Bitmasking
int x = 0b100101;
int mask = 0x01;
// First bit
((mask << 0) & x) ? 1 : 0
// Second bit
((mask << 1) & x) ? 1 : 0
...
etc.
In C, C++, and similarly-syntaxed languages, you can determine if the right-most bit in an integer i is 1 or 0 by examining whether i & 1 is nonzero or zero. (Note that that's a single & signifying a bitwise AND operation, not a && signifying logical AND.) For the second-to-the-right bit, you check i & 2; for the third you check i & 4, and so on by powers of two.
More generally, to determine if the bit that's jth from the right is zero, you can check whether i & (1 << (j-1)) != 0. The << indicates a left-shift; 1 << (j-1) is essentially equivalent to 2j-1.
Thus, for a 32-bit integer, your loop would look something like this:
unsigned int i = 26; /* Replace this with however it's actually defined. */
int j;
for (j = 31; j >= 0; j--)
{
if ((i & (1 << (j-1))) != 0)
/* do something for jth bit is 1 */
else
/* do something for jth bit is 0 */
}
Hopefully, that's enough to get you started.
Came across a similar problem so thought I'd share my solution. This is assuming your value is always one byte (8 bits)
Iterate over all 8 bits within the byte and check if that bit is set (you can do this by shifting the bit we are checking to the LSB position and masking it with 0x01)
int value = 26;
for (int i = 0; i < 8; i++) {
if ((value >> i) & 0x01) {
// Bit i is 1
printf("%d is set\n", i);
}
else {
// Bit i is 0
printf("%d is cleared\n", i);
}
}
I'm not exactly sure what you say you want to do. You could probably use bitmasks to do any bit-manipulation in your byte, if that helps.
Hi
Look up bit shifting and bitwise and.

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;
}

Bit reversal of an integer, ignoring integer size and endianness

Given an integer typedef:
typedef unsigned int TYPE;
or
typedef unsigned long TYPE;
I have the following code to reverse the bits of an integer:
TYPE max_bit= (TYPE)-1;
void reverse_int_setup()
{
TYPE bits= (TYPE)max_bit;
while (bits <<= 1)
max_bit= bits;
}
TYPE reverse_int(TYPE arg)
{
TYPE bit_setter= 1, bit_tester= max_bit, result= 0;
for (result= 0; bit_tester; bit_tester>>= 1, bit_setter<<= 1)
if (arg & bit_tester)
result|= bit_setter;
return result;
}
One just needs first to run reverse_int_setup(), which stores an integer with the highest bit turned on, then any call to reverse_int(arg) returns arg with its bits reversed (to be used as a key to a binary tree, taken from an increasing counter, but that's more or less irrelevant).
Is there a platform-agnostic way to have in compile-time the correct value for max_int after the call to reverse_int_setup(); Otherwise, is there an algorithm you consider better/leaner than the one I have for reverse_int()?
Thanks.
#include<stdio.h>
#include<limits.h>
#define TYPE_BITS sizeof(TYPE)*CHAR_BIT
typedef unsigned long TYPE;
TYPE reverser(TYPE n)
{
TYPE nrev = 0, i, bit1, bit2;
int count;
for(i = 0; i < TYPE_BITS; i += 2)
{
/*In each iteration, we swap one bit on the 'right half'
of the number with another on the left half*/
count = TYPE_BITS - i - 1; /*this is used to find how many positions
to the left (and right) we gotta move
the bits in this iteration*/
bit1 = n & (1<<(i/2)); /*Extract 'right half' bit*/
bit1 <<= count; /*Shift it to where it belongs*/
bit2 = n & 1<<((i/2) + count); /*Find the 'left half' bit*/
bit2 >>= count; /*Place that bit in bit1's original position*/
nrev |= bit1; /*Now add the bits to the reversal result*/
nrev |= bit2;
}
return nrev;
}
int main()
{
TYPE n = 6;
printf("%lu", reverser(n));
return 0;
}
This time I've used the 'number of bits' idea from TK, but made it somewhat more portable by not assuming a byte contains 8 bits and instead using the CHAR_BIT macro. The code is more efficient now (with the inner for loop removed). I hope the code is also slightly less cryptic this time. :)
The need for using count is that the number of positions by which we have to shift a bit varies in each iteration - we have to move the rightmost bit by 31 positions (assuming 32 bit number), the second rightmost bit by 29 positions and so on. Hence count must decrease with each iteration as i increases.
Hope that bit of info proves helpful in understanding the code...
The following program serves to demonstrate a leaner algorithm for reversing bits, which can be easily extended to handle 64bit numbers.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char**argv)
{
int32_t x;
if ( argc != 2 )
{
printf("Usage: %s hexadecimal\n", argv[0]);
return 1;
}
sscanf(argv[1],"%x", &x);
/* swap every neigbouring bit */
x = (x&0xAAAAAAAA)>>1 | (x&0x55555555)<<1;
/* swap every 2 neighbouring bits */
x = (x&0xCCCCCCCC)>>2 | (x&0x33333333)<<2;
/* swap every 4 neighbouring bits */
x = (x&0xF0F0F0F0)>>4 | (x&0x0F0F0F0F)<<4;
/* swap every 8 neighbouring bits */
x = (x&0xFF00FF00)>>8 | (x&0x00FF00FF)<<8;
/* and so forth, for say, 32 bit int */
x = (x&0xFFFF0000)>>16 | (x&0x0000FFFF)<<16;
printf("0x%x\n",x);
return 0;
}
This code should not contain errors, and was tested using 0x12345678 to produce 0x1e6a2c48 which is the correct answer.
typedef unsigned long TYPE;
TYPE reverser(TYPE n)
{
TYPE k = 1, nrev = 0, i, nrevbit1, nrevbit2;
int count;
for(i = 0; !i || (1 << i && (1 << i) != 1); i+=2)
{
/*In each iteration, we swap one bit
on the 'right half' of the number with another
on the left half*/
k = 1<<i; /*this is used to find how many positions
to the left (or right, for the other bit)
we gotta move the bits in this iteration*/
count = 0;
while(k << 1 && k << 1 != 1)
{
k <<= 1;
count++;
}
nrevbit1 = n & (1<<(i/2));
nrevbit1 <<= count;
nrevbit2 = n & 1<<((i/2) + count);
nrevbit2 >>= count;
nrev |= nrevbit1;
nrev |= nrevbit2;
}
return nrev;
}
This works fine in gcc under Windows, but I'm not sure if it's completely platform independent. A few places of concern are:
the condition in the for loop - it assumes that when you left shift 1 beyond the leftmost bit, you get either a 0 with the 1 'falling out' (what I'd expect and what good old Turbo C gives iirc), or the 1 circles around and you get a 1 (what seems to be gcc's behaviour).
the condition in the inner while loop: see above. But there's a strange thing happening here: in this case, gcc seems to let the 1 fall out and not circle around!
The code might prove cryptic: if you're interested and need an explanation please don't hesitate to ask - I'll put it up someplace.
#ΤΖΩΤΖΙΟΥ
In reply to ΤΖΩΤΖΙΟΥ 's comments, I present modified version of above which depends on a upper limit for bit width.
#include <stdio.h>
#include <stdint.h>
typedef int32_t TYPE;
TYPE reverse(TYPE x, int bits)
{
TYPE m=~0;
switch(bits)
{
case 64:
x = (x&0xFFFFFFFF00000000&m)>>16 | (x&0x00000000FFFFFFFF&m)<<16;
case 32:
x = (x&0xFFFF0000FFFF0000&m)>>16 | (x&0x0000FFFF0000FFFF&m)<<16;
case 16:
x = (x&0xFF00FF00FF00FF00&m)>>8 | (x&0x00FF00FF00FF00FF&m)<<8;
case 8:
x = (x&0xF0F0F0F0F0F0F0F0&m)>>4 | (x&0x0F0F0F0F0F0F0F0F&m)<<4;
x = (x&0xCCCCCCCCCCCCCCCC&m)>>2 | (x&0x3333333333333333&m)<<2;
x = (x&0xAAAAAAAAAAAAAAAA&m)>>1 | (x&0x5555555555555555&m)<<1;
}
return x;
}
int main(int argc, char**argv)
{
TYPE x;
TYPE b = (TYPE)-1;
int bits;
if ( argc != 2 )
{
printf("Usage: %s hexadecimal\n", argv[0]);
return 1;
}
for(bits=1;b;b<<=1,bits++);
--bits;
printf("TYPE has %d bits\n", bits);
sscanf(argv[1],"%x", &x);
printf("0x%x\n",reverse(x, bits));
return 0;
}
Notes:
gcc will warn on the 64bit constants
the printfs will generate warnings too
If you need more than 64bit, the code should be simple enough to extend
I apologise in advance for the coding crimes I committed above - mercy good sir!
There's a nice collection of "Bit Twiddling Hacks", including a variety of simple and not-so simple bit reversing algorithms coded in C at http://graphics.stanford.edu/~seander/bithacks.html.
I personally like the "Obvious" algorigthm (http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious) because, well, it's obvious. Some of the others may require less instructions to execute. If I really need to optimize the heck out of something I may choose the not-so-obvious but faster versions. Otherwise, for readability, maintainability, and portability I would choose the Obvious one.
Here is a more generally useful variation. Its advantage is its ability to work in situations where the bit length of the value to be reversed -- the codeword -- is unknown but is guaranteed not to exceed a value we'll call maxLength. A good example of this case is Huffman code decompression.
The code below works on codewords from 1 to 24 bits in length. It has been optimized for fast execution on a Pentium D. Note that it accesses the lookup table as many as 3 times per use. I experimented with many variations that reduced that number to 2 at the expense of a larger table (4096 and 65,536 entries). This version, with the 256-byte table, was the clear winner, partly because it is so advantageous for table data to be in the caches, and perhaps also because the processor has an 8-bit table lookup/translation instruction.
const unsigned char table[] = {
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF};
const unsigned short masks[17] =
{0,0,0,0,0,0,0,0,0,0X0100,0X0300,0X0700,0X0F00,0X1F00,0X3F00,0X7F00,0XFF00};
unsigned long codeword; // value to be reversed, occupying the low 1-24 bits
unsigned char maxLength; // bit length of longest possible codeword (<= 24)
unsigned char sc; // shift count in bits and index into masks array
if (maxLength <= 8)
{
codeword = table[codeword << (8 - maxLength)];
}
else
{
sc = maxLength - 8;
if (maxLength <= 16)
{
codeword = (table[codeword & 0X00FF] << sc)
| table[codeword >> sc];
}
else if (maxLength & 1) // if maxLength is 17, 19, 21, or 23
{
codeword = (table[codeword & 0X00FF] << sc)
| table[codeword >> sc] |
(table[(codeword & masks[sc]) >> (sc - 8)] << 8);
}
else // if maxlength is 18, 20, 22, or 24
{
codeword = (table[codeword & 0X00FF] << sc)
| table[codeword >> sc]
| (table[(codeword & masks[sc]) >> (sc >> 1)] << (sc >> 1));
}
}
How about:
long temp = 0;
int counter = 0;
int number_of_bits = sizeof(value) * 8; // get the number of bits that represent value (assuming that it is aligned to a byte boundary)
while(value > 0) // loop until value is empty
{
temp <<= 1; // shift whatever was in temp left to create room for the next bit
temp |= (value & 0x01); // get the lsb from value and set as lsb in temp
value >>= 1; // shift value right by one to look at next lsb
counter++;
}
value = temp;
if (counter < number_of_bits)
{
value <<= counter-number_of_bits;
}
(I'm assuming that you know how many bits value holds and it is stored in number_of_bits)
Obviously temp needs to be the longest imaginable data type and when you copy temp back into value, all the extraneous bits in temp should magically vanish (I think!).
Or, the 'c' way would be to say :
while(value)
your choice
We can store the results of reversing all possible 1 byte sequences in an array (256 distinct entries), then use a combination of lookups into this table and some oring logic to get the reverse of integer.
Here is a variation and correction to TK's solution which might be clearer than the solutions by sundar. It takes single bits from t and pushes them into return_val:
typedef unsigned long TYPE;
#define TYPE_BITS sizeof(TYPE)*8
TYPE reverser(TYPE t)
{
unsigned int i;
TYPE return_val = 0
for(i = 0; i < TYPE_BITS; i++)
{/*foreach bit in TYPE*/
/* shift the value of return_val to the left and add the rightmost bit from t */
return_val = (return_val << 1) + (t & 1);
/* shift off the rightmost bit of t */
t = t >> 1;
}
return(return_val);
}
The generic approach hat would work for objects of any type of any size would be to reverse the of bytes of the object, and the reverse the order of bits in each byte. In this case the bit-level algorithm is tied to a concrete number of bits (a byte), while the "variable" logic (with regard to size) is lifted to the level of whole bytes.
Here's my generalization of freespace's solution (in case we one day get 128-bit machines). It results in jump-free code when compiled with gcc -O3, and is obviously insensitive to the definition of foo_t on sane machines. Unfortunately it does depend on shift being a power of 2!
#include <limits.h>
#include <stdio.h>
typedef unsigned long foo_t;
foo_t reverse(foo_t x)
{
int shift = sizeof (x) * CHAR_BIT / 2;
foo_t mask = (1 << shift) - 1;
int i;
for (i = 0; shift; i++) {
x = ((x & mask) << shift) | ((x & ~mask) >> shift);
shift >>= 1;
mask ^= (mask << shift);
}
return x;
}
int main() {
printf("reverse = 0x%08lx\n", reverse(0x12345678L));
}
In case bit-reversal is time critical, and mainly in conjunction with FFT, the best is to store the whole bit reversed array. In any case, this array will be smaller in size than the roots of unity that have to be precomputed in FFT Cooley-Tukey algorithm. An easy way to compute the array is:
int BitReverse[Size]; // Size is power of 2
void Init()
{
BitReverse[0] = 0;
for(int i = 0; i < Size/2; i++)
{
BitReverse[2*i] = BitReverse[i]/2;
BitReverse[2*i+1] = (BitReverse[i] + Size)/2;
}
} // end it's all

Resources