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

one's complement ~ operator in c does not flip bits correctly?

我有一段代码:

#include <stdio.h>

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

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

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

0b11111101 是-3,不是-125。

0b10000011 将是 -125 而 0b00000011 将是 3.

你似乎在假设 sign-magnitude,这很不常见。

~ 运算符翻转所有位,但这些位对负数的含义取决于您的系统。 C 允许三种不同的表示形式:符号大小、ones' complement 和二进制补码。实际上,几乎总是使用二进制补码。


此外,C 不能真正对 chars 进行操作。当您尝试在表达式中使用 char 值时,它首先被提升为 int。所以 ~i 中实际发生的事情是:

  • 读取i的值(char 2)。
  • 转换为int (int 2).
  • 翻转所有位(int 0b1111111....111101,具体取决于您的 int 有多少位(通常为 32 或 64)。
  • 位按照补码表示,对应-3。

在这种情况下,结果与先对 char 进行运算,然后将结果转换为 int 的结果相同,因此没有区别,但就是这样C 做到了。