Reverse bit pattern in C - c

I am converting a number to binary and have to use putchar to output each number.
The problem is that I am getting the order in reverse.
Is there anyway to reverse a numbers bit pattern before doing my own stuff to it?
As in int n has a specific bit pattern - how can I reverse this bit pattern?

There are many ways to do this, some very fast. I had to look it up.
Reverse bits in a byte
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
Reverse an N-bit quantity in parallel in 5 * lg(N) operations:
unsigned int v; // 32-bit word to reverse bit order
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
Reverse bits in word by lookup table
static const unsigned char BitReverseTable256[256] =
{
# define R2(n) n, n + 2*64, n + 1*64, n + 3*64
# define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
# define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
R6(0), R6(2), R6(1), R6(3)
};
unsigned int v; // reverse 32-bit value, 8 bits at time
unsigned int c; // c will get v reversed
// Option 1:
c = (BitReverseTable256[v & 0xff] << 24) |
(BitReverseTable256[(v >> 8) & 0xff] << 16) |
(BitReverseTable256[(v >> 16) & 0xff] << 8) |
(BitReverseTable256[(v >> 24) & 0xff]);
// Option 2:
unsigned char * p = (unsigned char *) &v;
unsigned char * q = (unsigned char *) &c;
q[3] = BitReverseTable256[p[0]];
q[2] = BitReverseTable256[p[1]];
q[1] = BitReverseTable256[p[2]];
q[0] = BitReverseTable256[p[3]];
Please look at http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel for more information and references.

Pop bits off your input and push them onto your output. Multiplying and dividing by 2 are the push and pop operations. In pseudo-code:
reverse_bits(x) {
total = 0
repeat n times {
total = total * 2
total += x % 2 // modulo operation
x = x / 2
}
return total
}
See modulo operation on Wikipedia if you haven't seen this operator.
Further points:
What would happen if you changed 2 to 4? Or to 10?
How does this effect the value of n? What is n?
How could you use bitwise operators (<<, >>, &) instead of divide and modulo? Would this make it faster?
Could we use a different algorithm to make it faster? Could lookup tables help?

Let me guess: you have a loop that prints the 0th bit (n&1), then shifts the number right. Instead, write a loop that prints the 31st bit (n&0x80000000) and shifts the number left. Before you do that loop, do another loop that shifts the number left until the 31st bit is 1; unless you do that, you'll get leading zeros.
Reversing is possible, too. Somthing like this:
unsigned int n = 12345; //Source
unsigned int m = 0; //Destination
int i;
for(i=0;i<32;i++)
{
m |= n&1;
m <<= 1;
n >>= 1;
}

I know: that is not exactly C, but I think that is an interesting answer:
int reverse(int i) {
int output;
__asm__(
"nextbit:"
"rcll $1, %%eax;"
"rcrl $1, %%ebx;"
"loop nextbit;"
: "=b" (output)
: "a" (i), "c" (sizeof(i)*8) );
return output;
}
The rcl opcode puts the shifted out bit in the carry flag, then rcr recovers that bit to another register in the reverse order.

My guess is that you have a integer and you're attempting to convert it to binary?
And the "answer" is ABCDEFG, but your "answer" is GFEDCBA?
If so, I'd double check the endian of the machine you're doing it on and the machine the "answer" came from.

Here are functions I've used to reverse bits in a byte and reverse bytes in a quad.
inline unsigned char reverse(unsigned char b) {
return (b&1 << 7)
| (b&2 << 5)
| (b&4 << 3)
| (b&8 << 1)
| (b&0x10 >> 1)
| (b&0x20 >> 3)
| (b&0x40 >> 5)
| (b&0x80 >> 7);
}
inline unsigned long wreverse(unsigned long w) {
return ( ( w &0xFF) << 24)
| ( ((w>>8) &0xFF) << 16)
| ( ((w>>16)&0xFF) << 8)
| ( ((w>>24)&0xFF) );
}

Related

count number of ones in a given integer using only << >> + | & ^ ~ ! = [duplicate]

This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 7 years ago.
How to write a C program using only << >> + | & ^ ~ ! =
That counts the number of ones in a given integer?
Have a look at the Bit Twiddling hacks from Stanford. Here are some choices for your problem:
The naïve Approach
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; v >>= 1)
{
c += v & 1;
}
With a Lookup Table
static const unsigned char BitsSetTable256[256] =
{
# define B2(n) n, n+1, n+1, n+2
# define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
# define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
B6(0), B6(1), B6(1), B6(2)
};
unsigned int v; // count the number of bits set in 32-bit value v
unsigned int c; // c is the total bits set in v
// Option 1:
c = BitsSetTable256[v & 0xff] +
BitsSetTable256[(v >> 8) & 0xff] +
BitsSetTable256[(v >> 16) & 0xff] +
BitsSetTable256[v >> 24];
// Option 2:
unsigned char * p = (unsigned char *) &v;
c = BitsSetTable256[p[0]] +
BitsSetTable256[p[1]] +
BitsSetTable256[p[2]] +
BitsSetTable256[p[3]];
// To initially generate the table algorithmically:
BitsSetTable256[0] = 0;
for (int i = 0; i < 256; i++)
{
BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
}
Brian W. Kernighan's Approach
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}
There are some more algorithms, read the linked page for details.
It is impossible to do this using only << >> + | & ^ ~ ! =. You need some other punctuation such as {, }, (, ) and ;, and you need some letters too.
Here is a solution without digits:
int bc(unsigned int n){int c=!&n;while(n){c++;n&=n+~!&n;}return c;}
It uses only the operators mentioned, but only works on 2's complement architectures.
If you cannot use if, for nor while statements, the parallel sum works this way:
int bitcount32(unsigned int x) {
x = ((x >> 1) & 0x55555555) + (x & 0x55555555);
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);
x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff);
return (x >> 16) + (x & 0x0000ffff);
}
This function works for 32 bit ints, but can be modified to handle 16 or 64 bit ints. There are more compact solutions and possibly more efficient ones depending on your actual CPU performance here: How to count the number of set bits in a 32-bit integer?

How to interleave 2 booleans using bitwise operators?

Suppose I have two 4-bit values, ABCD and abcd. How to interleave it, so it becomes AaBbCcDd, using bitwise operators? Example in pseudo-C:
nibble a = 0b1001;
nibble b = 0b1100;
char c = foo(a,b);
print_bits(c);
// output: 0b11010010
Note: 4 bits is just for illustration, I want to do this with two 32bit ints.
This is called the perfect shuffle operation, and it's discussed at length in the Bible Of Bit Bashing, Hacker's Delight by Henry Warren, section 7-2 "Shuffling Bits."
Assuming x is a 32-bit integer with a in its high-order 16 bits and b in its low-order 16 bits:
unsigned int x = (a << 16) | b; /* put a and b in place */
the following straightforward C-like code accomplishes the perfect shuffle:
x = (x & 0x0000FF00) << 8 | (x >> 8) & 0x0000FF00 | x & 0xFF0000FF;
x = (x & 0x00F000F0) << 4 | (x >> 4) & 0x00F000F0 | x & 0xF00FF00F;
x = (x & 0x0C0C0C0C) << 2 | (x >> 2) & 0x0C0C0C0C | x & 0xC3C3C3C3;
x = (x & 0x22222222) << 1 | (x >> 1) & 0x22222222 | x & 0x99999999;
He also gives an alternative form which is faster on some CPUs, and (I think) a little more clear and extensible:
unsigned int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 8)) & 0x0000FF00; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F0; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x22222222; x = x ^ t ^ (t << 1);
I see you have edited your question to ask for a 64-bit result from two 32-bit inputs. I'd have to think about how to extend Warren's technique. I think it wouldn't be too hard, but I'd have to give it some thought. If someone else wanted to start here and give a 64-bit version, I'd be happy to upvote them.
EDITED FOR 64 BITS
I extended the second solution to 64 bits in a straightforward way. First I doubled the length of each of the constants. Then I added a line at the beginning to swap adjacent double-bytes and intermix them. In the following 4 lines, which are pretty much the same as the 32-bit version, the first line swaps adjacent bytes and intermixes, the second line drops down to nibbles, the third line to double-bits, and the last line to single bits.
unsigned long long int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ull; x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ull; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ull; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0Cull; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x2222222222222222ull; x = x ^ t ^ (t << 1);
From Stanford "Bit Twiddling Hacks" page:
https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableObvious
uint32_t x = /*...*/, y = /*...*/;
uint64_t z = 0;
for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // unroll for more speed...
{
z |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
}
Look at the page they propose different and faster algorithms to achieve the same.
Like so:
#include <limits.h>
typedef unsigned int half;
typedef unsigned long long full;
full mix_bits(half a,half b)
{
full result = 0;
for (int i=0; i<sizeof(half)*CHAR_BIT; i++)
result |= (((a>>i)&1)<<(2*i+1))|(((b>>i)&1)<<(2*i+0));
return result;
}
Here is a loop-based solution that is hopefully more readable than some of the others already here.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
uint64_t interleave(uint32_t a, uint32_t b) {
uint64_t result = 0;
int i;
for (i = 0; i < 31; i++) {
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
result <<= 1;
}
// Skip the last left shift.
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
return result;
}
void printBits(uint64_t a) {
int i;
for (i = 0; i < 64; i++)
printf("%lu", (a >> (63 - i)) & 1);
puts("");
}
int main(){
uint32_t a = 0x9;
uint32_t b = 0x6;
uint64_t c = interleave(a,b);
printBits(a);
printBits(b);
printBits(c);
}
I have used the 2 tricks/operations used in this post How do you set, clear, and toggle a single bit? of setting a bit at particular index and checking the bit at particular index.
The following code is implemented using these 2 operations only.
int a = 0b1001;
int b = 0b1100;
long int c=0;
int index; //To specify index of c
int bit,i;
//Set bits in c from right to left.
for(i=32;i>=0;i--)
{
index=2*i+1; //We have to add the bit in c at this index
//Check a
bit=a&(1<<i); //Checking whether the i-th bit is set in a
if(bit)
c|=1<<index; //Setting bit in c at index
index--;
//Check b
bit=b&(1<<i); //Checking whether the i-th bit is set in b
if(bit)
c|=1<<index; //Setting bit in c at index
}
printf("%ld",c);
Output: 210 which is 0b11010010

Reverse unsigned short vector using bitwise operator

I want reverse the binary
unsigned short gf_t = 44 // = 00101100
in 00110100 in C language. How i will able to for that using bitwise operators?
pdta: My computer have 32 bits pattern.
When in doubt, see the Bit Twiddling Hacks page. In fact, there you can find a very simple algorithm that does what you want...
Reverse bits the obvious way
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
On October 15, 2004, Michael Hoisie pointed out a bug in the original version. Randal E. Bryant suggested removing an extra operation on May 3, 2005. Behdad Esfabod suggested a slight change that eliminated one iteration of the loop on May 18, 2005. Then, on February 6, 2007, Liyong Zhou suggested a better version that loops while v is not 0, so rather than iterating over all bits it stops early.
There is also, however, several nifty approaches documented there. You can look into those and try to understand them for learning :-) For example, here is one particular interesting form...
Reverse an N-bit quantity in parallel in 5 * lg(N) operations:
unsigned int v; // 32-bit word to reverse bit order
// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
Note that if sizeof(unsigned short) * CHAR_BIT is 16, the appropriate usage would only require the first 4 transpositions -- see as follows:
unsigned short v;
// swap odd and even bits
v = ((v >> 1) & 0x5555) | ((v & 0x5555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x3333) | ((v & 0x3333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0F0F) | ((v & 0x0F0F) << 4);
// swap bytes
v = ((v >> 8) & 0x00FF) | ((v & 0x00FF) << 8);
That being said, why not just use uint16_t (if it's available)?
Here is working example (see ideone):
#include <stdio.h>
#include <assert.h>
#include <stdint.h>
inline uint16_t reverse(uint16_t v) {
v = ((v >> 1) & 0x5555) | ((v & 0x5555) << 1); /* swap odd/even bits */
v = ((v >> 2) & 0x3333) | ((v & 0x3333) << 2); /* swap bit pairs */
v = ((v >> 4) & 0x0F0F) | ((v & 0x0F0F) << 4); /* swap nibbles */
v = ((v >> 8) & 0x00FF) | ((v & 0x00FF) << 8); /* swap bytes */
return v;
}
main() {
uint16_t gf_t = 44;
printf("%hu\n", reverse(gf_t));
}
You can do it like this (v is a 16-bit number):
v = ((v >> 1) & 0x5555) | ((v & 0x5555) << 1);
v = ((v >> 2) & 0x3333) | ((v & 0x3333) << 2);
v = ((v >> 4) & 0x0F0F) | ((v & 0x0F0F) << 4);
v = ((v >> 8) & 0x00FF) | ((v & 0x00FF) << 8);
The first line swaps the odd and even bits
The second line swaps consecutive pairs
The third line swaps groups of four bits
The last line swaps the two bytes
You can find more tricks like this here. Here is a link to ideone with this code snippet.
If you are trying to make sense of this, write binary representations of the "magic numbers" used in the example:
0x5555 is 0101010101010101
0x3333 is 0011001100110011
0x0F0F is 0000111100001111
0x00FF is 0000000011111111
The & operation clears out the "unwanted" bits; the shifts reposition the desired parts over the "zero gaps" opened up by the masking operation, and finally the | re-combines the two parts.
Normally you and the input with 1 to get its LSB. Or that into the result. Shift the result left a bit and the input right a bit. Repeat for a total of 32 iterations.
The binary is 0000000000101100 - There are 16 bits in a short.
// includes go here
int main() {
unsigned short gf_t = 44;
cout << hex << gf_t << endl;
unsigned short gf_r = 0;
for ( int iter = 0; iter < sizeof(short) * 8; ++iter )
{
unsigned short tmp = gf_t;
tmp = tmp & 1;
gf_r = (gf_r << 1 ) | tmp;
gf_t = gf_t >> 1;
}
cout << hex << gf_r << endl;
}

Hamming weight written only in binary operations?

I need to write an expression of one byte Hamming weight in terms of binary operations only (&, ^, >>); without any loop, just a formula.
I know that there are plenty algorithms, that allow computing Hamming weight, but all of them use arithmetical operations or looping.
If we take an algorithm from http://en.wikipedia.org/wiki/Hamming_weight, then the first sum D=B+C can be written as D = B^C^(B&C << 1), but two following sums are more complicated.
Does anyone have a hint?
UPDATE:
Thank you for help guys. Actually, I needed something like following:
int popcount_1(unsigned char in){
unsigned char m1 = 0x55;
unsigned char m2 = 0x33;
unsigned char m4 = 0x0f;
unsigned char B,C = 0;
unsigned char x = in;
x = (x & (x << 1) & (m1 << 1)) | (m1 & (x ^ (x >> 1)));
B = x & m2;
C = (x >> 2) & m2;
x = B ^ C ^ ((B & C) << 1);
B = (x & m4 ) ^ ((x >> 4) & m4);
C = (x & ((x >> 4) & m4)) << 1;
x = B ^ C ^ ((B & C) << 1);
return x;
}
This code will result in Hamming weight of variable in. It does not contain any +, -, or comparison instructions and it can work on 8bits microcontrollers.
Nevertheless, it takes more operations than most of other solutions. Now, I am trying to simplify it.
UPDATE2: Another solution, based on 64 bits registers, is proposed by #Evgeny Kluev
I think the best you can do is O(log n). Here is code (in Go) for the pop-count of a 32-bit integer. Extending this to 64-bits should be obvious if you need it, hopefully the comments make it clear what is actually going on:
func popCount(n uint32) int {
// each bit in n is a one-bit integer that indicates how many bits are set
// in that bit.
n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555)
// Now every two bits are a two bit integer that indicate how many bits were
// set in those two bits in the original number
n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333)
// Now we're at 4 bits
n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F)
// 8 bits
n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF)
// 16 bits
n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF)
// kaboom - 32 bits
return int(n)
}
I'm not sure if this is what you search for, but here is just a formula using only shifts and bitwise and:
int weight(unsigned char x)
{
return ((0x876543210 >>
(((0x4332322132212110 >> ((x & 0xF) << 2)) & 0xF) << 2)) >>
((0x4332322132212110 >> (((x & 0xF0) >> 2)) & 0xF) << 2))
& 0xf;
}
Here shift operation is twice used as a substitute for array indexing (to find 4-bit hamming weights). And one more shift operation uses array indexing to perform addition.

bit swapping with char type in C

the data type is char, and the pattern is follow:
source byte: [0][1][2][3][4][5][6][7]
destination: [6][7][4][5][2][3][0][1]
for example, if I pass a char, 29 to this function, it will do the swapping and return a char type value, which is 116.
How can I do the swapping?
thank you.
========================
Just wondering if I can do in this way?
unsigned char mask = 128;
char num = 0, value1 = 29;
int i, a;
for(i = 0; i < 8; i++) {
if (i == 0 || i == 1 || i == 6 || i == 7)
a = 6;
else
a = 2;
if(i < 4)
num = ((value1 & mask) >> a);
else
num = ((value1 & mask) << a);
result = (result | num);
if(i<7)
mask = mask >> 1;
}
I usually number my bits the other way -- so that bit 0 is the LSB. Following your numbering scheme:
unsigned char src = 29;
unsigned char dst = 0;
dst = (((src & 0x80) >> 6) | // bit 0
((src & 0x40) >> 6) | // bit 1
((src & 0x20) >> 2) | // bit 2
((src & 0x10) >> 2) | // bit 3
((src & 0x08) << 2) | // bit 4
((src & 0x04) << 2) | // bit 5
((src & 0x02) << 6) | // bit 6
((src & 0x01) << 6) // bit 7
);
Unless of course, you're numbering them "the right way", but drawing them "backwards" -- then just reverse what I've done above. (Not that I'm trying to start a religious war here...)
or a lookup table
just in case you dont understand that. Here is more detail
For each of the 256 possible inputs work out the answer (by hand)
then do
unsigned char answers[256] = {0x00, 0x40,0x21.....};
unsigned char answer = answers[input];
I hasten to add that the values I gave are an example - and are certainly not correct
See the "Reversing bit sequences" section on Bit Twiddling Hacks.
Also, if you want to do it yourself:
To read the n-th bit: int bit = value & (1 << n); If the bit is not set, bit is 0.
To set the n-th bit: value |= 1 << n; (value = value OR (1 shifted by n digits))
To clear the n-th bit: value &= ~(1 << n); (value = value AND NOT (1 shifted by n digits))
First swap the lower four bits with the higher four bits, then swap all adjacent pairs of bits:
dst = src;
dst = ((dst & 0xF0) >> 4) | ((dst & 0x0F) << 4);
dst = ((dst & 0xCC) >> 2) | ((dst & 0x33) << 2);
You may find this helpful:
http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
but it the bit reversal there isn't exactly what you need. With just a little work you could change the "obvious" algorithm to do what you want.
source byte: [01][23][45][67] to
destination: [67][45][23][01]
Implementation:
unsigned char shiftit( unsigned char in ) {
unsigned char out;
out = (
(( in & 0xC0 ) >> 6) + /* top 2 to bottom 2 */
(( in & 0x30 ) >> 2) + /* centre-left 2 to centre-right */
(( in & 0x0C ) << 2) + /* centre-right 2 to centre-left */
(( in & 0x03 ) << 6) /* bottom 2 to top 2 */
);
return( out );
}
Returns 116 when called shiftit( 29 ).
Rotate through carry http://en.wikipedia.org/wiki/Bitwise_operation#Rotate_through_carry
So this would work:
myByte = myByte << 2 | myByte >> 6;

Resources