【问题标题】:Decimal to binary wrong output十进制转二进制错误输出
【发布时间】:2018-03-19 10:14:19
【问题描述】:

我正在尝试使用这两种方法以二进制形式打印一个数字:

方法一:

int input;
scanf("%d", &input);

for(int i = sizeof(int)*CHAR_BIT - 1; i >= 0; i--)
printf("%u",(input & (1<<i)) >> i);

方法二:

int input;
scanf("%d", &input);

for(int i = sizeof(int)*CHAR_BIT - 1; i >= 0; i--)
(input & (1<<i)) ? putchar('1') : putchar('0');

方法 2 工作正常,但在方法 1 中打印的第一个“数字”是 4294967295,我找不到错误。

【问题讨论】:

标签: c binary bit-shift


【解决方案1】:

使用有符号数进行位移是没有意义的。当您将数据移入int 的符号位时,您会调用未定义的行为。另请注意,1 文字的类型为 int。

通过使用无符号类型来解决这个问题,同时摆脱原生 C 类型,有利于 stdint.h。

uint32_t input = 0x88776655;

for(uint32_t i=0; i<32; i++)
{
  printf("%u", (input & (1u<<31-i)) >> 31-i);
}

【讨论】:

    【解决方案2】:

    在使用位之前通过强制转换为无符号类型来解决这个问题。

    printf("%u", ((unsigned int)input & (1 << i)) >> i);
    

    【讨论】:

    • 1 &lt;&lt; i 和 i==31 still 调用未定义的行为。这是我在这个帖子中第四次指出这一点。
    【解决方案3】:

    使用无符号类型并注意 i>=0 比较。因为无符号类型总是 >=0。它不能是负数。

    unsigned int input;
    scanf("%u", &input);
    for(unsigned int i = sizeof(int)*8 - 1; ; i--) {
        printf("%u",(input & (1u<<i)) >> i);
        if ( i==0 ) break ;
    }
    printf("\n") ;
    

    【讨论】:

    • 此代码也调用未定义的行为,就像原始代码一样。即当i 是31 并且你做1&lt;&lt;i。请注意,移位运算符不会导致此处隐式类型提升为无符号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2015-12-12
    • 1970-01-01
    • 2015-07-19
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多