c中的一个补码运算符不能正确翻转位?

时间:2017-10-02 04:04:21

标签: c binary unary-operator

我有一大堆代码:

#include <stdio.h>

int main() {
    char i = 0b00000010; //2
    printf("%d", ~i);
}

如果一元运算符~翻转所有位,~i应该等于0b11111101 这是-125,但我的代码为我提供了-3的输出,二进制为0b00000011。 有人可以解释一下为什么吗?

1 个答案:

答案 0 :(得分:4)

假设two's complement代表负数(这是您的机器最有可能使用的数字):

0b11111101是-3,而不是-125。

0b10000011为-125,而0b00000011为3。

你似乎假设sign-magnitude,这是非常罕见的。

~运算符翻转所有位,但这些位对负数的意义取决于您的系统。 C允许三种不同的表示:符号幅度,ones' complement和两个补码。在实践中,几乎总是使用两个补充。

此外,C无法真正对char进行操作。当您尝试在表达式中使用char值时,它会首先提升为int。那么~i中实际发生的是:

  • 读取i的值(char 2)。
  • 它已转换为intint 2)。
  • 所有位都被翻转(int 0b1111111....111101,具体取决于您int的位数(通常为32或64)。
  • 根据二进制补码表示来解释这些位,对应于-3。

在这种情况下,结果与您首先在char上完成操作,然后将结果转换为int相同,因此没有区别,但这是如何C做到了。