无法正确打印十进制到二进制数



我正在尝试编写代码来打印数字的二进制表示形式。这是我的尝试:

#include <stdio.h>
void getBinary(int num);
int main(void) {
int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
int mask = 1 << 31, i;
int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("n");
}

这是行不通的。如果我使 num = 2,我的输出将是...0011.这是我得到的答案:

void getBinary(int);
int main()
{
int num=0;
printf("Enter an integer number :");
scanf("%d",&num);
printf("nBinary value of %d is =",num);
getBinary(num);
return 0;
}
/*Function definition : getBinary()*/
void getBinary(int n)
{
int loop;
/*loop=15 , for 16 bits value, 15th bit to 0th bit*/
for(loop=15; loop>=0; loop--)
{
if( (1 << loop) & n)
printf("1");
else
printf("0");
}
}

这将给出正确的输出。为什么?我的代码和这个有什么不同。他们不是在用更少的步骤对解决方案做同样的事情吗?

#include <stdio.h>
void getBinary(int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
unsigned int mask = 1 << 31;
int i;
unsigned int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("n");
}

对于那些好奇的人来说,这是正确的答案。只需使面具未签名即可。

代码中存在一些问题:

  • 1 << 31调用由于有符号算术溢出而未定义的行为。在您的平台上,它最有可能产生值INT_MIN,它具有预期的位配置,但为负数。

  • temp > 0如果num < 0,可能会错误地失败,因为符号位也会使temp负数。

  • mask的值为负时,将向右移动具有实现定义的结果:在您的平台上,它会复制符号位,因此mask不会像预期的那样具有单个位,而是设置在当前位之上的所有位。这解释了观察到的行为。

你应该在函数getBinary中使用类型unsigned int进行numtempmask以获得正确的行为。

下面是代码的更正版本:

#include <stdio.h>
void getBinary(unsigned int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(unsigned int num) {
unsigned int mask = 1U << 31;
unsigned int temp;
for (int i = 31; i >= 0; i--) {
temp = num & mask;
if (temp != 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("n");
}

建议的解决方案仅打印 16 位,这可能是也可能不是规范。如果int类型大于 16 位,则位移不会溢出,一切正常。 如果int有 16 位,1 << 15调用未定义的行为,因此解决方案并不严格正确,但可以在大多数当前平台上运行。

这是一个更简单的解决方案:

void getBinary(unsigned int num) {
for (int shift = 32; shift-- > 0;) {
putchar('0' + ((num >> shift) & 1));
}
putchar("n");
}

shift初始化为16以仅打印低阶 16 位。

最新更新