C中的反转位模式

我正在将数字转换为二进制数,并且必须使用putchar输出每个数字。

问题是我正在接受订单。

在做自己的后缀之前,有没有反转数字位模式?

因为在int中有一个特定的位模式 – 我该如何反转这个位模式?

有很多方法可以做到这一点,有些方法非常快。 我不得不查一查。

一个字节中的反转位

 b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; 

在5 * lg(N)操作中并行反转N位数量:

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

通过查找表反转字中的位

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

有关更多信息和参考,请查看http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel 。

从输入中弹出位并将它们推到输出上。 乘以除以2是推送和弹出操作。 在伪代码中:

 reverse_bits(x) { total = 0 repeat n times { total = total * 2 total += x % 2 // modulo operation x = x / 2 } return total } 

如果您还没有看到此运算符,请参阅Wikipedia上的模运算。

更多要点:

  • 如果你改变2到4会发生什么? 还是10?
  • 这如何影响n的值? 什么是n?
  • 你怎么能使用按位运算符( <<>>& )而不是除法和模数? 这会让它更快吗?
  • 我们可以使用不同的算法来加快速度吗? 查找表有帮助吗?

让我猜一下:你有一个循环打印第0位(n和1),然后向右移动数字。 相反,写一个打印第31位(n&0x80000000)并将数字左移的循环。 在执行该循环之前,执行另一个循环,将数字向左移动,直到第31位为1; 除非你那样做,否则你会得到前导零。

也可以逆转。 像这样的东西:

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

我知道:这不完全是C,但我认为这是一个有趣的答案:

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

rcl操作码将移出的位置于进位标志中,然后rcr以相反的顺序将该位恢复到另一个寄存器。

我的猜测是你有一个整数而你正在尝试将其转换为二进制?

“答案”是ABCDEFG,但你的“答案”是GFEDCBA?

如果是这样的话,我会仔细检查你正在进行的机器的端部和机器的“答案”来自。

以下是我用来反转字节中的位和反转四字节中的字节的函数。

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