Finding Bit Positions in an unsigned 32-bit integer - c
I think I might have been asleep in my CS class when they talked about Bit Positions, so I am hoping someone can lend a hand.
I have a unsigned 32-bit integer (Lets use the value: 28)
According to some documentation I am going over, the value of the integer contains flags specifying various things.
Bit positions within the flag are numbered from 1 (low-order) to 32 (high-order).
All undefined flag bits are reserved and must be set to 0.
I have a Table that shows the meanings of the flags, with meaning for the numbers 1-10.
I am hoping that someone can try and explain to me what this all means and how to find the "flag" value(s) from a number like, 28, based off of bit position.
Thanks
28 converts to 11100 in binary. That means bits 1 and 2 are not set and bits 3, 4 and 5 are set.
A few points: first, anybody who's really accustomed to C will usually start the numbering at 0, not 1. Second, you can test of individual flags with the bitwise and operator (&), as in:
#define flag1 1 // 1 = 00 0001
#define flag2 2 // 2 = 00 0010
#define flag3 4 // 4 = 00 0100
#define flag4 8 // 8 = 00 1000
#define flag5 16 // 16 = 01 0000
#define flag6 32 // 32 = 10 0000
if (myvalue & flag1)
// flag1 was set
if (myvalue & flag4)
// flag4 was set
and so on. You can also check which bits are set in a loop:
#include <stdio.h>
int main() {
int myvalue = 28;
int i, iter;
for (i=1, iter=1; i<256; i<<=1, iter++)
if (myvalue & i)
printf("Flag: %d set\n", iter);
return 0;
}
should print:
Flag: 3 set
Flag: 4 set
Flag: 5 set
Instead of looping through every single bit, you can instead loop through only the set bits, which can be faster if you expect bits to be sparsely set:
Assume the bit field is in (scalar integer) variable field.
while (field){
temp = field & -field; //extract least significant bit on a 2s complement machine
field ^= temp; // toggle the bit off
//now you could have a switch statement or bunch of conditionals to test temp
//or get the index of the bit and index into a jump table, etc.
}
Works pretty well when the bit field is not limited to the size of a single data type, but could be of some arbitrary size. In that case, you can extract 32 (or whatever your register size is) bits at a time, test it against 0, and then move on to the next word.
To get an int with the value 0 or 1 representing just the nth bit from that integer, use:
int bitN = (value >> n) & 1;
But that's not usually what you want to do. A more common idiom is this:
int bitN = value & (1 << n);
In this case bitN will be 0 if the nth bit is not set, and non-zero in the case that the nth bit is set. (Specifically, it'll be whatever value comes out with just the nth bit set.)
Assuming flags is unsigned...
int flag_num = 1;
while (flags != 0)
{
if ((flags&1) != 0)
{
printf("Flag %d set\n", flags);
}
flags >>= 1;
flag_num += 1;
}
If flags is signed you should replace
flags >>= 1;
with
flags = (flags >> 1) & 0x7fffffff;
Use a log function, with base 2. In python, that would look like:
import math
position = math.log(value, 2)
If position is not an integer, then more than 1 bit was set to 1.
A slight variation of #invaliddata's answer-
unsigned int tmp_bitmap = x;
while (tmp_bitmap > 0) {
int next_psn = __builtin_ffs(tmp_bitmap) - 1;
tmp_bitmap &= (tmp_bitmap-1);
printf("Flag: %d set\n", next_psn);
}
// You can check the bit set positions of 32 bit integer.
// That's why the check is added "i != 0 && i <= val" to iterate till
// the end bit position.
void find_bit_pos(unsigned int val) {
unsigned int i;
int bit_pos;
printf("%u::\n", val);
for(i = 1, bit_pos = 1; i != 0 && i <= val; i <<= 1, bit_pos++) {
if(val & i)
printf("set bit pos: %d\n", bit_pos);
}
}
An MSVC variation of #boolAeon's answer
#include <vector>
#include <intrin.h>
std::vector<unsigned long> poppos(const unsigned long input)
{
std::vector<unsigned long> result;
result.reserve(sizeof(input) * CHAR_BIT);
unsigned long num = input;
unsigned long index = -1;
while (_BitScanForward(&index, num))
{
result.push_back(index);
num &= num - 1;
}
return result;
}
Let's say that you have an array of integers, and you want to find all the positions (32-bit positions) where the bits are set collectively i.e. for a particular bit position how many set bits you will have in total by considering all the integers. In this case what you can do is that check for every Integer and mark its set bit position :
// let arr[n] is an array of integers of size n.
int fq[33] = {0} // frequency array that will contain frequency of set bits at a particular position as 1 based indexing.
for(int i=0; i<n; i++) {
int x = arr[i];
int pos = 1; // bit position
for(int i=1; i<=pow(2,32); i= i<<1) { // i is the bit mask for checking every position and will go till 2^32 because x is an integer.
if(x & i) fq[pos]++;
pos++;
}
}
Related
Get list of bits set in BitMap
In C, Is there any optimized way of retrieving list of BitPositions set without parsing through each bit. Consider following example int bitmap[4]; So, there are 4 * 32 Bit Positions..Values are following bitmap = { 0x1, 0x0, 0x0, 0x0010001 } I want retrieve Position of each bit set instead of parsing from 0 to 4 * 32 positions.
First of all, one cannot really use int for bitmap in C, because shifting a bit to left to the sign bit has undefined behaviour, C doesn't guarantee that the representation is two's complement, or that there are 32 bits in an int; that being said the easiest way to avoid these pitfalls is to use the uint32_t from <stdint.h> instead. Thus #include <stdint.h> uint32_t bitmap[4]; So consider that you number these bits 0 ... 127 from indexes 0 ... 3; and within indexes 0 ... 31; so, you can get the index into array and the bit number within that value by using the following formula: int bit_number = // a value from 0 ... 127 int index = value >> 32; // shift right by number of bits in each index int bit_in_value = value & 31; // take modulo 32 to get the bit in value Now you can index the integer by: bitmap[index]; and the bit mask for the desired value is uint32_t mask = (uint32_t)1 << bit_in_value; so you can check if the bit is set by doing bit_is_set = !!(bitmap[index] & mask); Now to speed things up, you can skip any index for which bitmap[index] is 0 because it doesn't contain any bits set; likewise, within each index you can speed things up by shifting bits in the uint32_t from the bitmap right by 1 and masking with 1; and breaking the loop when the uint32_t becomes 0: for (int index = 0; index <= 3; index ++) { uint32_t entry = bitmap[index]; if (! entry) { continue; } int bit_number = 32 * index; while (entry) { if (entry & 1) { printf("bit number %d is set\n", bit_number); } entry >>= 1; bit_number ++; } } Other than that there is not much to speed up, besides lookup tables, or using compiler intrinsics, such as this to set which is the lowest bit set but you'd still have to use some anyway.
An optimal solution which runs in O(k), where k = the total number of set bits in your entire list, can be achieved by using a lookup table. For example, you can use a table of 256 entries to describe the bit positions of every set bit in that byte. The index would be the actual value of the Byte. For each entry you could use the following structure. struct { int numberOfSetBits; char* list; // use malloc and alloocate the list according to numberOfSetBits } You can then iterate across the list member of each structure and the number of iterations = the number of set bits for that byte. For a 32-bit integer you will have to iterate through 4 of these structs, one per each byte. To determine which entry you need to check you use a Bitmap and shift 8 bits. Note, that the bit positions are relative to that byte, so you may have to add an offset or either 24, 16, or 8 depending on the byte you are iterating through (assuming a 32 bit integer). Note: if additional memory usage is not a problem for you, you could build a 64K Table of 16-bit entries and you will decrease the number of your structs by half.
Related with this question, you can see What is the fastest way to return the positions of all set bits in a 64-bit integer? A simple solution, but perhaps not the fastest, depending on the times of the log and pow functions: #include<math.h> #include<stdio.h> void getSetBits(unsigned int num, int offset){ int bit; while(num){ bit = log2(num); num -= pow(2, bit); printf("%i\n", offset + bit); // use bit number } } int main(){ int i, bitmap[4] = {0x1, 0x0, 0x0, 0x0010001}; for(i = 0; i < 4; i++) getSetBits(bitmap[i], i * 32); } Complexity O(D) | D is the number of set bits.
How to return multiple bits from a number in C
I have a function to extract a single bit from a number: int getBit (int value, int position) { return value & (1 << position)); } But how do I do it for a range (both for signed and unsigned numbers)? For instance: get bits 10:14 from 0x12345678 (signed 0) = 0x15 int getField (int value, int hi, int lo, bool isSigned)
I suspect you might want to approach the entire problem in a different way. Rather than extracting bits, why not just use bit masks. For example, to check if the most significant bit in a byte is enabled: if(byte & 0xf0) {} To check for the least significant bit it would be: if(byte & 0x01) {} To check for multiple (or a "range") of bits, say the low order nibble: if(byte & 0x0f) {} From what you've said, I suspect this is much closer to what you want and much simpler than shifting to extract bits.
You just have to create a mask: int createMask(int a, int b){ int c = a; int mask = 0; /*First we set the lenght of the mask*/ while(c <= b){ /*Including b*/ mask <<= 1; mask = mask|1; c++; } /*Then we set the position to the mask, the first bit is in the position 0*/ c=0; while(c<a){ c++; mask <<= 1 ; } return mask; } I haven't tested the function yet, but its just for explaining a way to make a mask. And the final function may be something like this: int getBits(int value, int a, int b){ int mask = createMask(a, b); mask &= value; //Now we have to move the bits to the right while(a>0){ mask >>= 1; a--; } return mask; } An example, if you want the first 6 bits, you have to code: getBits(myValue, 0, 5). Im not sure what did you mean about the signeds and unsigneds numbers, but i hope it can help you. Srry for my english.
That was a bit of fun :) In three easy steps: shift your value right by the amount lo and decrease hi with lo. This simplifies the problem to 'get the lowest hi bits'. clip off the highest bits -- a custom mask is created on the fly. if necessary, use the highest bit to sign-extend the result (bitfiddling based on Sign extending from a constant bit width in C#). I don't know the reason for the suggested function prototype, but I would suggest using the order lo, hi rather than hi, lo. Somehow 10,14 feels more natural than the other way around, even though bits count down from high to low, when counted left to right -- the computer is supposed to make things easier for us! #include <stdio.h> #include <stdbool.h> int getField (int value, int hi, int lo, bool isSigned) { /* step 1: clip off lower bits */ value >>= lo; hi -= lo-1; /* step 2: clip off higher bits */ value &= ~(-1<<hi); /* step 3: extend sign */ if (isSigned && (value & (1<<(hi-1)))) value |= -(1<<hi); return value; } int main (void) { int i; i = getField (0x123456c8, 14,10, true); printf ("i = %d / %Xh\n", i,i); return 0; } Result: i = -11 / FFFFFFF5h which is the correct bit set: 16 12 8 4 0 <- bit position ...4 5 6 7 8 <- value 0100 0101 0110 0111 1000 <- bitwise --- -- <- mask 101 01 <- result ..111101 01 < sign extended result
Iterate through bits in C
I have a big char *str where the first 8 chars (which equals 64 bits if I'm not wrong), represents a bitmap. Is there any way to iterate through these 8 chars and see which bits are 0? I'm having alot of trouble understanding the concept of bits, as you can't "see" them in the code, so I can't think of any way to do this.
Imagine you have only one byte, a single char my_char. You can test for individual bits using bitwise operators and bit shifts. unsigned char my_char = 0xAA; int what_bit_i_am_testing = 0; while (what_bit_i_am_testing < 8) { if (my_char & 0x01) { printf("bit %d is 1\n", what_bit_i_am_testing); } else { printf("bit %d is 0\n", what_bit_i_am_testing); } what_bit_i_am_testing++; my_char = my_char >> 1; } The part that must be new to you, is the >> operator. This operator will "insert a zero on the left and push every bit to the right, and the rightmost will be thrown away". That was not a very technical description for a right bit shift of 1.
Here is a way to iterate over each of the set bits of an unsigned integer (use unsigned rather than signed integers for well-defined behaviour; unsigned of any width should be fine), one bit at a time. Define the following macros: #define LSBIT(X) ((X) & (-(X))) #define CLEARLSBIT(X) ((X) & ((X) - 1)) Then you can use the following idiom to iterate over the set bits, LSbit first: unsigned temp_bits; unsigned one_bit; temp_bits = some_value; for ( ; temp_bits; temp_bits = CLEARLSBIT(temp_bits) ) { one_bit = LSBIT(temp_bits); /* Do something with one_bit */ } I'm not sure whether this suits your needs. You said you want to check for 0 bits, rather than 1 bits — maybe you could bitwise-invert the initial value. Also for multi-byte values, you could put it in another for loop to process one byte/word at a time.
It's true for little-endian memory architecture: const int cBitmapSize = 8; const int cBitsCount = cBitmapSize * 8; const unsigned char cBitmap[cBitmapSize] = /* some data */; for(int n = 0; n < cBitsCount; n++) { unsigned char Mask = 1 << (n % 8); if(cBitmap[n / 8] & Mask) { // if n'th bit is 1... } }
In the C language, chars are 8-bit wide bytes, and in general in computer science, data is organized around bytes as the fundamental unit. In some cases, such as your problem, data is stored as boolean values in individual bits, so we need a way to determine whether a particular bit in a particular byte is on or off. There is already an SO solution for this explaining how to do bit manipulations in C. To check a bit, the usual method is to AND it with the bit you want to check: int isBitSet = bitmap & (1 << bit_position); If the variable isBitSet is 0 after this operation, then the bit is not set. Any other value indicates that the bit is on.
For one char b you can simply iterate like this : for (int i=0; i<8; i++) { printf("This is the %d-th bit : %d\n",i,(b>>i)&1); } You can then iterate through the chars as needed. What you should understand is that you cannot manipulate directly the bits, you can just use some arithmetic properties of number in base 2 to compute numbers that in some way represents some bits you want to know. How does it work for example ? In a char there is 8 bits. A char can be see as a number written with 8 bits in base 2. If the number in b is b7b6b5b4b3b2b1b0 (each being a digit) then b>>i is b shifted to the right by i positions (in the left 0's are pushed). So, 10110111 >> 2 is 00101101, then the operation &1 isolate the last bit (bitwise and operator).
If you want to iterate through all char. char *str = "MNO"; // M=01001101, N=01001110, O=01001111 int bit = 0; for (int x = strlen(str)-1; x > -1; x--){ // Start from O, N, M printf("Char %c \n", str[x]); for(int y=0; y<8; y++){ // Iterate though every bit // Shift bit the the right with y step and mask last position if( str[x]>>y & 0b00000001 ){ printf("bit %d = 1\n", bit); }else{ printf("bit %d = 0\n", bit); } bit++; } } output Char O bit 0 = 1 bit 1 = 1 bit 2 = 1 bit 3 = 1 bit 4 = 0 bit 5 = 0 bit 6 = 1 bit 7 = 0 Char N bit 8 = 0 bit 9 = 1 bit 10 = 1 ...
Fastest way to count number of bit transitions in an unsigned int
I'm looking for the fastest way of counting the number of bit transitions in an unsigned int. If the int contains: 0b00000000000000000000000000001010 The number of transitions are: 4 If the int contains: 0b00000000000000000000000000001001 The number of transitions are: 3 Language is C.
int numTransitions(int a) { int b = a >> 1; // sign-extending shift properly counts bits at the ends int c = a ^ b; // xor marks bits that are not the same as their neighbors on the left return CountBits(c); // count number of set bits in c } For an efficient implementation of CountBits see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
Fastest depends on your scenario: As you specified your datatype as constant sized (unsigned int), it is possible with lookup table. But when you need this operation only once the constant overhead to init the table is too big, and scanning+counting through the int is far faster despite. I guess the overall best would be a combination: Look up table for a byte or word (256 or 64k entries is not so much), and then combine the bytes/words by their last/first bit.
In C/C++ I would do the following: unsigned int Transitions(unsigned int value) { unsigned int result = 0; for (unsigned int markers = value ^ (value >> 1); markers; markers = markers >> 1) { if (markers & 0x01) result++; } return result; }
Here's the code using arithmetic shift + xor and Kernighan's method for bit counting: int count_transitions(int x) { assert((-1 >> 1) < 0); // check for arithmetic shift int count = 0; for(x ^= (x >> 1); x; x &= x - 1) ++count; return count; }
What language? I would loop 64 times and then bit shift your number to inspect of the bits, then store the previous bit and compare it to the current one. If it's different, incremember your count.
Ok, with transitions you mean if you walk through the string of 0-s and 1-s, you count each occurance that a 0 follows a 1 or a 1 follows a 0. This is easy by shifting bits out and counting the changes: transitions(n) result = 0 prev = n mod 2 n = n div 2 while n<>0 if n mod 2 <> prev then result++ prev = n mod 2 fi n = n div 2 elihw return result you can replace the mod and div with shifts.
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