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.
=======开发者_如何学C=================
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;
精彩评论