views:

185

answers:

7

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

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.

nategoose
+2  A: 

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))

DarkDust
A: 

Rotate through carry http://en.wikipedia.org/wiki/Bitwise_operation#Rotate_through_carry

So this would work:

myByte = myByte << 2 | myByte >> 6;
Matt Williamson
Easy in assembler, but how would you do that in C ?
DarkDust
Updated with the answer.
Matt Williamson
It works for me but I don't know why. Surely shifting right 8 bits yields zero?
PP
ah, you're right. it needs to be 6 (8-2).
Matt Williamson
+4  A: 

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

pm100
+1 This operation seems significantly complex that an overhead of 256 bytes may be your best option.
cobbal
+4  A: 

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...)

bstpierre
There are obvious ways to make this more efficient. I'm leaving the code above as-is for clarity, optimization is left as an exercise to the reader.
bstpierre
Downvoter must be an Other-Endian? ;)
bstpierre
I'd say the numbering of the bits doesn't matter for this problem.
jdv
@jdv - Agreed, since it is symmetrical.
bstpierre
thanks, it works
Tim
can i do this way?
Tim
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 else num = ((value1 mask = mask >> 1; if(i == 7) num = num; else num = (num | num);
Tim
+1  A: 

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);
sth
A: 
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 ).

PP