Reverse unsigned short vector using bitwise operator - c

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

Related

How to read reversed number from a binary file?

i would like to read a 32-bits number from binary file in C. The problem is that the order of bits is reversed. For an example 3 digits number 110 would stand for 3, not for 6. At the beginning we have the least significant bit (2^0), then 2^1 and so on. Is there any simple way to do this in C, or do i have to write all the logic by myself (read the first bit, multiply it by 2^0, add to the sum, repeat to the end)?
you have many possible ways:
Portable:
(not my algorithm)
uint32_t rev(uint32_t x)
{
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
return((x >> 16) | (x << 16));
}
or
uint32_t bit_reverse_4bytes(uint32_t x)
{
x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4);
x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2);
return ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1);
}
Naive
uint32_t naiverevese(uint32_t x)
{
uint32_t result = 0;
for(int i = 0; i < 32; i++)
{
result |= x & 1;
result <<=1;
x >>= 1;
}
return result;
}
or lookup table.
Not portable but the most efficient:
Many processors have a special instructions for it for example:
ARM - rbit and the intrinsic unsigned int __rbit(unsigned int val)

How to reverse an int but grouped by 2 bit in C?

Like this:
input: 10010011
(10->01->00->11)
output: 11000110
(11->00->01->10)
input: 11010001
(11->01->00->01)
output: 01000111
(01->00->01->11)
Anyone has any ideas about that?
Fewer operations than lserni's algorithm:
uint32_t reverseByTwo(uint32_t value) {
value = ((value & 0x03030303) << 2) | ((value >> 2) & 0x03030303); // swap adjacent pairs
value = ((value & 0x0F0F0F0F) << 4) | ((value >> 4) & 0x0F0F0F0F); // swap nibbles
value = ((value & 0x00FF00FF) << 8) | ((value >> 8) & 0x00FF00FF); // swap bytes
value = ((value & 0x0000FFFF) << 16) | ((value >> 16) & 0x0000FFFF);
return value;
}
For 64-bit values just add another swap for the 32-bit halves, for smaller types, just leave out the last few swaps.
Weird request. I'd do it like this:
uint32_t reverseByTwo(uint32_t value)
{
int i;
uint32_t new_value = 0;
for (i = 0; i < 16; i++)
{
new_value <<= 2;
new_value |= (value & 0x3);
value >>= 2;
}
return new_value;
}
At each iteration, the two LSB of value are placed in the two LSB of new_value, which is shifted to the left.
For an eight-bit value,
uint8_t reverseByTwo(uint8_t value)
{
int i;
uint32_t new_value = 0;
for (i = 0; i < 4; i++)
{
new_value <<= 2;
new_value |= (value & 0x3);
value >>= 2;
}
return new_value;
}
if performances are at a premium, you can manually unroll the loop (GCC should do this by itself, but sometimes doesn't bother) and declare the function as inline.
new_value = 0;
// new_value <<= 2; // First time not necessary
new_value |= (value & 0x3);
value >>= 2;
new_value <<= 2;
new_value |= (value & 0x3);
value >>= 2;
new_value <<= 2;
new_value |= (value & 0x3);
value >>= 2;
new_value <<= 2;
new_value |= (value & 0x3);
// value >>= 2;
return new_value;
The fastest possible way to transform the bits in a single byte (char) into another single byte is to build yourself an array:
unsigned char rev[256];
rev[0] = 0; /* 00000000 -> 00000000 */
...
rev[147] = 198; /* 10010011 -> 11000110 */
...
rev[198] = 147; /* 11000110 -> 10010011 */
...
rev[255] = 255; /* 11111111 -> 11111111 */
To convert a number x to its bit-reversed form, just write rev[x]. If you have multiple bytes to convert, such as in a 4-byte int, just look up the 4 bytes in the rev table.
You'll need to convert binary to another base (here, I use decimal) when writing this code, because C doesn't have binary constants (which would be ten times more useful than octal constants).
You could also put the values into the initializer, but you'll have to count positions to make sure everything is in the right place. (Maybe write a little program to do it!)
unsigned char rev[256] = {0, ..., 198, ..., 147, ..., 255};
Fill in the ... with all the other numbers in the right places.
$x = (($x & 0x33333333) << 2) | (($x & 0xCCCCCCCC) >> 2);
$x = (($x & 0x0F0F0F0F) << 4) | (($x & 0xFOFOFOFO) >> 4);
$x = (($x & 0x00FF00FF) << 8) | (($x & 0xFF00FF00) >> 8);
$x = (($x & 0x0000FFFF) << 16) | (($x & 0xFFFF0000) >> 16);
To give credit where due, this algorithm came from "Hacker's Delight" by Henry S. Warren, Jr. The only difference is that the algorithm in the book didn't reverse by pairs; it just reversed the bits.
#include <limits.h>
#define INT_BITS (sizeof(int) * CHAR_BIT)
unsigned reverse_bits(unsigned x) {
#define PAIR(i) ((((x) >> (i*2)) & 3) << (INT_BITS - (i+1)*2))
unsigned result = 0;
unsigned i;
for(i = 0; i < INT_BITS/2; i++) {
result |= PAIR(i);
}
return result;
}
Though this will do it for an unsigned int, whereas you might want to replace int and unsigned there with char and unsigned char.
If you want the fastest possible:
output =
((input & 0xc0) >> 6) |
((input & 0x30) >> 2) |
((input & 0xc) << 2) |
((input & 0x3) << 6);
You have bits (ab cd ef gh) and want (gh ef cd ab)
If you multiply by 0x101 and store in 16 bit int, you get (ab cd ef gh ab cd ef gh).
Then you have your bit pattern in that number in two group of four bits:
(00 00 ef 00 ab 00 00 00),
(00 00 00 gh 00 cd 00 00)
So you just have to shift and mask appropriately
unsigned char swap_bit_pairs(unsigned char b)
{
unsigned int a = 0x101*b;
return ((a >> 6) & 0x33) | ((a >> 2) & 0xCC);
}
So it's possible in 6 operations
EDIT: oups! I wrote 0x66 instead of 0xCC

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.

reverse the bits using bit field in c language?

how to reverse the bits using bit wise operators in c language
Eg:
i/p: 10010101
o/p: 10101001
If it's just 8 bits:
u_char in = 0x95;
u_char out = 0;
for (int i = 0; i < 8; ++i) {
out <<= 1;
out |= (in & 0x01);
in >>= 1;
}
Or for bonus points:
u_char in = 0x95;
u_char out = in;
out = (out & 0xaa) >> 1 | (out & 0x55) << 1;
out = (out & 0xcc) >> 2 | (out & 0x33) << 2;
out = (out & 0xf0) >> 4 | (out & 0x0f) << 4;
figuring out how the last one works is an exercise for the reader ;-)
Knuth has a section on Bit reversal in The Art of Computer Programming Vol 4A, bitwise tricks and techniques.
To reverse the bits of a 32 bit number in a divide and conquer fashion he uses magic constants
u0= 1010101010101010, (from -1/(2+1)
u1= 0011001100110011, (from -1/(4+1)
u2= 0000111100001111, (from -1/(16+1)
u3= 0000000011111111, (from -1/(256+1)
Method credited to Henry Warren Jr., Hackers delight.
unsigned int u0 = 0x55555555;
x = (((x >> 1) & u0) | ((x & u0) << 1));
unsigned int u1 = 0x33333333;
x = (((x >> 2) & u1) | ((x & u1) << 2));
unsigned int u2 = 0x0f0f0f0f;
x = (((x >> 4) & u2) | ((x & u2) << 4));
unsigned int u3 = 0x00ff00ff;
x = (((x >> 8) & u3) | ((x & u3) << 8));
x = ((x >> 16) | (x << 16) mod 0x100000000); // reversed
The 16 and 8 bit cases are left as an exercise to the reader.
Well, this might not be the most elegant solution but it is a solution:
int reverseBits(int x) {
int res = 0;
int len = sizeof(x) * 8; // no of bits to reverse
int i, shift, mask;
for(i = 0; i < len; i++) {
mask = 1 << i; //which bit we are at
shift = len - 2*i - 1;
mask &= x;
mask = (shift > 0) ? mask << shift : mask >> -shift;
res |= mask; // mask the bit we work at at shift it to the left
}
return res;
}
Tested it on a sheet of paper and it seemed to work :D
Edit: Yeah, this is indeed very complicated. I dunno why, but I wanted to find a solution without touching the input, so this came to my haead

Reverse bit pattern in 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) );
}

Resources