NOT 按位运算符会破坏无符号整数?

NOT bitwise operator breaks unsigned integers?

我试图让 C 将倒置​​的无符号整数解释为无符号整数。 如何在 C 不将其解释为二进制补码的情况下反转无符号数的位?

每当我有一个无符号整数并将其用作按位 NOT 运算符的操作数时,根据二进制补码,它的计算结果为负数。然而根据定义我使用的是无符号整数,一个不应该有符号的数字

下面是我的沙盒代码。我目前使用的是 GCC 版本 9.1.1。

#include <stdio.h>
#include <stdint.h>

int main(){
   uint8_t x = 1;//0000 0001
   printf("NOT(%d) == %d", x, ~x);//1111 1110
}

我想要 254 (1111 1110) 的输出,但 C 将该值解释为二进制补码,所以我得到 -2。有没有办法让 C 将反转字节解释为二进制补码?

在 C 中,当表达式中使用比 int 窄的整数时,它会自动提升为 int。这样,在~x中,自动将uint8_t转换为int,然后按位进行~,再将结果传递给printf作为 int。所以打印的是反转 int 的所有位的结果,而不仅仅是 uint8_t.

的位

要获得 uint8_t 结果,请将表达式转换为 uint8_t:

printf("NOT(%d) == %d", x, (uint8_t) ~x);

请注意,在执行 uint8_t 转换后,该值将再次自动提升为 int,因此 printf 在任何一种情况下都会收到 int。但是,转换会将值减少为 uint8_t 中可表示的值,这就是将要打印的值。

但是,到 uint8_t 的转换使用 int 作为源类型,因此 ~x 的位将根据实现的 int 格式进行解释.要在不依赖 int 格式的情况下获取 ~x 的低位,您可以使用 & 0xff 提取它们而不是使用强制转换:

printf("NOT(%d) == %d", x, ~x & 0xff);

或者,您可以对 unsigned 值而不是 int 值执行按位 ~

printf("NOT(%d) == %d", x, (uint8_t) ~ (unsigned) x);