2010-04-24 56 views
3

我很惭愧地承认,我不太了解位和位操作,因为我可能应该这样做。我试着通过写一些'反转位的顺序'和'计数ON位'的功能来修复这个周末。我举了一个here的例子,但是当我实现它时,我发现我必须循环,而< 29.如果我循环,而< 32(如在示例中)然后,当我尝试打印整数(使用printBits函数我写了)我似乎错过了前3位。这对我来说没有意义,有人可以帮我吗?这个倒序位顺序函数是怎么回事?

感谢大家的帮助,我添加了评论以显示我所做的更改。

int reverse(int n) 
{ 
    int r = 0; 
    int i = 0; 
    for(i = 0; i < 29; i++) //Should be i < 32 
    { 
     r = (r << 1) + (n & 1); //| instead of + to make it obvious I'm handling bits 
     n >>=1; 
    } 

    return r; 
} 

这里是我的printBits功能:

void printBits(int n) 
{ 
    int mask = 0X10000000; //unsigned int mask = 0X80000000; 
    while (mask) 
    { 
     if (mask & n) 
     { 
      printf("1"); 
     } 
     else 
     { 
      printf("0"); 
     } 
     mask >>= 1; 
    } 
    printf("\n"); 
} 

和工作?反向功能

int reverse2(int n) 
{ 
    int r = n; 
    int s = sizeof(n) * 7; // int s = (sizeof(n) * 8) -1 

    for (n >>= 1; n; n >>=1) 
    { 
     r <<=1; 
     r |= n & 1; 
     s--; 


    r <<= s; 
    return r; 
} 
+1

记住你的循环是从零开始的。所以32是从0到31 ... – 2010-04-24 19:52:48

+0

您是否可以发布您的PrintBits函数,以防万一出现问题?它可能有帮助。 :-) – Jaxidian 2010-04-24 19:54:43

+0

此外,为了跟进托尼的评论,这是一个整数,一个有符号的整数,所以你丢失了一点,因为存储符号(+/-)。所以现在循环是从0到30。也许你失去了一次必要的迭代,因为对于n位,你需要循环n-1次。考虑一下 - 你必须做多少班次才能扭转2位? 3位?等等...... – Jaxidian 2010-04-24 19:56:21

回答

3

您有:

int mask = 0x10000000; 

这里有两个问题。你没有设置高位,如果你这样做了,它仍然(可能)不起作用,因为你的编译器会在签名的int上使用算术移位。

你想你的面具更改为:

unsigned int mask = 0x80000000; 

对于算术移位,移位0x80000000权永远不会变成零,符号位将被神奇地扩展到其他位。有关算术移位的更多细节,请参见here

2

相反的+,你应该使用|(按位或)。你应该使用< 32

+1

'+'和'|'在这里会给出相同的结果。 – interjay 2010-04-24 19:55:29

+0

'+'或'|'在这里没有区别,'+'可能更清晰,为什么使用'|'? – 2010-04-24 19:55:52

+5

@Chris Dodd:'|'更清晰。你正在处理的是位,而不是算术。因此使用设计用于位操作的操作符。 – Ponkadoodle 2010-04-24 19:57:48

1

正如所写,这会将n的低29位反转为r。 n的前三位将留在n中(向下移位29位)并不返回。

如果你看到别的东西,我会怀疑你的printBits函数有问题。

编辑

你printBits函数打印n的低29位,所以这一切才有意义。

3

打印位错误,其0x80000000不是0x10000000。

>>> bin (0x80000000) 
'0b10000000000000000000000000000000' 
>>> bin (0x10000000) 
'0b10000000000000000000000000000' 

请参阅0x1 ...不设置最高位。

5
int mask = 0X10000000; 

将第28位置1。您想要0X80000000