2017-08-11 54 views
-2

我遇到了这个程序,将小数转换成它们在C中的二进制等价物。我不明白printf语句在这个程序中是如何工作的。请解释这个程序是如何工作的?

int main() 
{ 
    int N; 
    scanf("%d", &N); // Enter decimal equivalent here 
    for(int j = floor(log2(N)); j >= 0; j--){ 
     printf("%d", (N >> j) & 1); 
    } 
} 
+2

我可以告诉你,它正在以一种非常糟糕的方式做它正在做的事情。所以你最好问问怎么做,而不是去尝试去理解一些奇怪的事情。 –

+3

你知道,如果你只是用手写出来和谷歌什么运营商>>和&做,并通过for循环逻辑,你会明白。 –

+0

我对&1感到困惑,任何东西和1本身都是 –

回答

1

让我们举个例子,通过这个问题来获得。假设你输入N = 65。它的二进制表示是-1000001.当你的代码通过它时,j将从floor开始(log2(65)),这是6.所以,给定的循环将运行7次,这意味着将打印出7个数字(这符合65的二进制表示有7位数的事实)。

循环内部 - 数字每次向右移动j位。当1000001向右移6位时,它变为0000001.如果移位5,则为0000010,依此类推。它下降到原始数字0位的移位。当这些移位的数字中的每一个都是1时,只有最低有效位(最右边的位)保持不变。并且这个数字可以是0或者1.

如果你会注意到每个右移都将数字除以2.所以当1000001移动1使得0100000时,它是32的二进制表示,它实际上C是65/2。毕竟,这是某人手动计算数字的二进制表示的方式。除以2的每个除法给出一个表示的数字(从结尾开始),并且该数字是0或1. &有助于获得0或1.

最后,65变为1000001

+0

感谢您的答案,但我不明白实际转换(小数到二进制)在这个程序中发生的地方?你写了“循环内 - 数字每次向右移动j位”。你在这个声明中说的是哪一个数字?如果这里的数字与转换发生的十进制数字是二进制等价的? – sportmew

+0

好的。现在我懂了。无需回复我先前的评论。你的解释清楚了一切。 – sportmew

1

它是什么做的是:

  • 发现数量最多j这样2^j <= N
  • j个位(从右边开始计数)开始,并向右移动...
    • 斩掉当前所选位右侧的所有位
    • 斩去所有位的当前选择位
    • 左侧打印剩下的一个位的值
+0

谢谢。现在我明白这个代码里发生了什么。另一个精心设计的答案使一切变得清晰。 – sportmew