C无符号整数的反转位

我正在使用按位运算符将无符号整数转换为二进制,并且当前执行整数&1以检查位是1还是0并输出,然后右移1除以2.但是这些位以错误的顺序返回(反转),所以我想在开始之前反转整数中的位顺序。

有一个简单的方法吗?

示例:所以如果我给了unsigned int 10 = 1010

while (x not eq 0) if (x & 1) output a '1' else output a '0' right shift x by 1 

这会返回0101,这是不正确的…所以我想在运行循环之前反转最初的位顺序,但我不确定如何做到这一点?

反转一个字中的位是令人讨厌的,只是以相反的顺序输出它们更容易。 例如,

 void write_u32(uint32_t x) { int i; for (i = 0; i < 32; ++i) putchar((x & ((uint32_t) 1 << (31 - i)) ? '1' : '0'); } 

这是反转位顺序的典型解决方案:

 uint32_t reverse(uint32_t x) { x = ((x >> 1) & 0x55555555u) | ((x & 0x55555555u) << 1); x = ((x >> 2) & 0x33333333u) | ((x & 0x33333333u) << 2); x = ((x >> 4) & 0x0f0f0f0fu) | ((x & 0x0f0f0f0fu) << 4); x = ((x >> 8) & 0x00ff00ffu) | ((x & 0x00ff00ffu) << 8); x = ((x >> 16) & 0xffffu) | ((x & 0xffffu) << 16); return x; } 

你可以从左向右移动,即将一个从MSB移到LSB,例如:

 unsigned n = 20543; unsigned x = 1<<31; while (x) { printf("%u ", (x&n)!=0); x = x>>1; } 

你可以直接从大端到小端循环。

 #define N_BITS (sizeof(unsigned) * CHAR_BIT) #define HI_BIT (1 << (N_BITS - 1)) for (int i = 0; i < N_BITS; i++) { printf("%d", !!(x & HI_BIT)); x <<= 1; } 

哪里!! 也可以写!=0>> (N_BITS - 1)

您可以像输出它们一样反转这些位,而是将它们存储在另一个整数中,然后再次执行:

 for (i = 0; i < (sizeof(unsigned int) * CHAR_BIT); i++) { new_int |= (original_int & 1); original_int = original_int >> 1; new_int = new_int << 1; } 

或者你可以做相反的事情,转移你的面具:

 unsigned int mask = 1 << ((sizeof(unsigned int) * CHAR_BIT) - 1); while (mask > 0) { bit = original_int & mask; mask = mask >> 1; printf("%d", (bit > 0)); } 

如果你想删除前导0,你可以等待1打印,或者做一个初步的尝试:

 unsigned int mask = 1 << ((sizeof(unsigned int) * CHAR_BIT) - 1); while ((mask > 0) && ((original_int & mask) == 0)) mask = mask >> 1; do { bit = original_int & mask; mask = mask >> 1; printf("%d", (bit > 0)); } while (mask > 0); 

这样你就可以将面具放在第一个要打印的1上,而忘记前导0

但请记住:打印整数的二进制值只需使用printf

 unsigned int rev_bits(unsigned int input) { unsigned int output = 0; unsigned int n = sizeof(input) << 3; unsigned int i = 0; for (i = 0; i < n; i++) if ((input >> i) & 0x1) output |= (0x1 << (n - 1 - i)); return output; } 

反转整数位的最佳方法是:

  1. 它非常有效。
  2. 它只在最左边的位为1时运行。

代码链接

 int reverse ( unsigned int n ) { int x = 0; int mask = 1; while ( n > 0 ) { x = x << 1; if ( mask & n ) x = x | 1; n = n >> 1; } return x; } 

我提出了一个解决方案,它不涉及任何按位运算符的应用。 它在空间和时间方面都是低效的。

 int arr[32]; for(int i=0;i<32;i++) { arr[i]=A%2; A=A/2; } double res=1; double re=0; for(int i=0;i<32;i++) { int j=31-i; res=arr[i]; while(j>0) { res=res*2; j--; } re=re+res; } cout<<(unsigned int )re; 

这是一个整数反转位的golang版本,如果有人正在寻找一个。 我在c中用类似于字符串反向的方法写了这个。 从第0位到第15位(31/2),将位i与位(31-i)交换。 请检查以下代码。

 package main import "fmt" func main() { var num = 2 //swap bits at index i and 31-i for i between 0-15 for i := 0; i < 31/2; i++ { swap(&num, uint(i)) } fmt.Printf("num is %d", num) } //check if bit at index is set func isSet(num *int, index uint) int { return *num & (1 << index) } //set bit at index func set(num *int, index uint) { *num = *num | (1 << index) } //reset bit at index func reSet(num *int, index uint) { *num = *num & ^(1 << index) } //swap bits on index and 31-index func swap(num *int, index uint) { //check index and 31-index bits a := isSet(num, index) b := isSet(num, uint(31)-index) if a != 0 { //bit at index is 1, set 31-index set(num, uint(31)-index) } else { //bit at index is 0, reset 31-index reSet(num, uint(31)-index) } if b != 0 { set(num, index) } else { reSet(num, index) } }` 

您可以使用以下reverse函数反转unsigned 32-bit integer并返回:

 unsigned int reverse(unsigned int A) { unsigned int B = 0; for(int i=0;i<32;i++){ unsigned int j = pow(2,31-i); if((A & (1< 

请记住包含数学库。 快乐编码:)

我认为问题是如何以相反的顺序输出。

有趣的答案(递归):

 #include  void print_bits_r(unsigned int x){ if(x==0){ printf("0"); return; } unsigned int n=x>>1; if(n!=0){ print_bits_r(n); } if(x&1){ printf("1"); }else{ printf("0"); } } void print_bits(unsigned int x){ printf("%u=",x); print_bits_r(x); printf("\n"); } int main(void) { print_bits(10u);//1010 print_bits((1<<5)+(1<<4)+1);//110001 print_bits(498598u);//1111001101110100110 return 0; } 

预期产量:

 10=1010 49=110001 498598=1111001101110100110 

顺序版本(首先选择高位):

 #include //Defines CHAR_BIT //.... void print_bits_r(unsigned int x){ //unsigned int mask=(UINT_MAX>>1)+1u;//Also works... unsigned int mask=1u<<(CHAR_BIT*sizeof(unsigned int)-1u); int start=0; while(mask!=0){ if((x&mask)!=0){ printf("1"); start=1; }else{ if(start){ printf("0"); } } mask>>=1; } if(!start){ printf("0"); } } 

Dietrich Epp的第二个答案可能是具有高速缓存的现代处理器的最佳选择。 然而,在典型的微控制器上并非如此,并且以下不仅更快,而且更通用且更紧凑(在C中):

 // reverse a byte uint8_t reverse_u8(uint8_t x) { const unsigned char * rev = "\x0\x8\x4\xC\x2\xA\x6\xE\x1\x9\x5\xD\x3\xB\x7\xF"; return rev[(x & 0xF0) >> 4] | (rev[x & 0x0F] << 4); } // reverse a word uint16_t reverse_u16(uint16_t x) { return reverse_u8(x >> 8) | (reverse_u8(x & 0xFF) << 8); } // reverse a long uint32_t reverse_u32(uint32_t x) { return reverse_u16(x >> 16) | (reverse_u16(x & 0xFFFF) << 16); } 

代码很容易翻译成Java,Go,Rust等。当然,如果你只需要打印数字,最好只需按相反顺序打印(参见Dietrich Epp的答案)。