为什么这个位移工作? (用于打印数字为二进制)

时间:2014-12-09 00:35:07

标签: c bit-manipulation

我看到了代码,并想知道为什么这有效:

#include <stdio.h>


void printBinary (unsigned int number)
{
 unsigned int mask = 0;

    for(mask = 1 << 31; mask!=0; mask >>=1)

      {
    if (number & mask)
        printf("1");
    else
        printf("0");

      }
printf ("\n");
}

int main()
{
    printBinary (10);
    return 0;

    unsigned int suffix = 24;


    return 0;
}

我想象这样的void函数: 起初我们有

掩码:100000000000000 ......(32次零)和 号码:0000000000000000000001010

它将两个数字与&amp;它们是不同的,因此发布了0。 下一循环:

010亿...

0000000000000000000001010

在这里。

00000000000000001000

00000000000000001010

(数字和掩码)将为真,但两个数字仍然不同。它只是比较当前1处于较高数字的二进制数。但是,由于比较了掩模和数字,如果它们完全相同,它应该只打印1。所以我不明白为什么在这里打印1而不是0。我认为只有在打印出来时才会打印1

0000000000000001010

0000000000000001010

我希望很清楚我的问题是什么,也许有人可以向我解释这个循环是如何运作的。

谢谢!

4 个答案:

答案 0 :(得分:3)

&是一个按位AND运算,所以

00000000000000001000 & 00000000000000001010 

评估为

00000000000000001000

与0不同,在C

if (number & mask)

的简写
if ((number & mask) != 0)

答案 1 :(得分:2)

这项工作由这个算法完成:

   for(mask = 1 << 31; mask!=0; mask >>=1) {
     if (number & mask)
        printf("1");
     else
        printf("0");
    }

首先要理解的是“掩码” - 这里的掩码是一个32位整数,其中1位完全设置为1,其他所有都为零。您似乎已经理解掩模以“1000000 ... 000”开始,并且在每个连续循环中,掩码中的“1”向右移动(掩码&gt;&gt; = 1)。因此,连续循环迭代的顺序是:“01000 .... 000”,“001000 ... 000”,...“0000 ... 00010”,“0000 ... 00001”

接下来就是“&amp;”运算符 - “逐位AND” - 当两个数字“逐位”并在一起时,结果将仅在两个输入都有1位的位置有1位。因此,例如,“00010”&amp; “11010”==“00010”。由于你的“掩码”只有1位设置,如果数字中相同位置的位为1,则(数字和掩码)的结果将与掩码本身相同,否则将为0。

最后,我们注意到在C中,0为假,而其他ANYTHNG则为真。

因此,我们可以按如下方式阅读上面的循环:

For each bit from position 31 to position 0:
    if that bit is a 1 in the number:
        print 1
    else:
        print 0

Voila - 号码以二进制形式打印。

答案 2 :(得分:1)

按位AND(&)结果是一个数字,其中设置了2个操作数中设置的所有位(1)。 这意味着,如果单个位匹配,就像您观察到的那样,结果将是一个非零数字,其值为TRUE

答案 3 :(得分:1)

您对代码的分析非常正确。 但是你还没有完全理解按位&amp;运营商工作。

&amp;的输出该表给出了2位的数据

       bit 2
        1  0
        ____
bit   0|0  0 
  1   1|1  0 

对于更大的数字&amp;依次比较每个数字中相同索引处的位并根据上表生成输出,因此如果两个输入中的同一位置中存在1,则输出中只有1。因此,对于您的示例数字,您将获得

00000000000000001000  //input 1
00000000000000001010  //input 2

00000000000000001000  //output

现在任何非零数字都等于true,因此if语句将进入打印“1”的情况。我更喜欢更明确的代码

if( (number & mask) != 0 )

基本上所有循环正在进行的是一次一个地处理数字并测试它是1还是零并打印相应的字符。