【问题标题】:Negation operator on unsigned charunsigned char 上的否定运算符
【发布时间】:2023-03-20 09:28:01
【问题描述】:
#include <stdio.h>
int main() {
    unsigned char a = 5;
    printf("%d\n",~a);
    printf("%d\n",a=~a);
    return 0;
}

根据此处接受的答案 Negation inside printf ,在第一个 printf 中,a 应该被提升为 int 并且输出应该是一个很大的负数。但是第一个 printf 的输出是 -6。您能解释一下为什么输出是 -6 以及为什么在这种情况下 char 没有提升为 int 吗?

【问题讨论】:

  • 你为什么期望一个巨大的负数?在链接的问题中,FFFFFFFB 被打印出来,即十六进制的-5
  • @AdrianMole 我说的是 OP 链接到的问题,而不是这个问题。
  • ! 是逻辑否定。 - 是算术否定。 ~ 是按位补码。
  • "并且输出应该是一个很大的负数。" --> 不完全。

标签: c bitwise-operators negation integer-promotion


【解决方案1】:

你能解释一下为什么输出是 -6 以及为什么在这种情况下 char 没有提升为 int 吗?

不是真的,因为它被提升为int - 并且,作为int,将反转所有位(假设two's-complement notation和无溢出)将正值n 转换为负值-(n+1)

对您的代码的这种修改可能会证明正在发生的事情:

#include <stdio.h>
int main()
{
    int a = 5;
    printf("%d\n", ~a); // Prints -6
    printf("%d\n", a = (unsigned char)~a); // Prints 250 - lower 8 bits of the int
    return 0;
}

【讨论】:

    【解决方案2】:

    它正在升级,~5 == -6 在二进制补码中。假设二进制补码,一个小的正数的按位否定将产生一个小的负数。只有当被视为unsigned 时,该数字才会显得很大,这就是链接答案中的"%X" 所做的。

    (顺便说一句,在打印为"%X" 之前,链接答案中的数字也应该转换为unsigned,因为printf 在技术上要求转换说明符和传递参数的类型之间完全对应)。

    【讨论】:

      【解决方案3】:

      对于二进制补码内部表示,如果你有一个整数值x,那么表达式

      x + ~x + 1
      

      等于 0。

      所以对于这个声明

      unsigned char a = 5;
      

      表达式~a的操作数将被提升为int类型。

      所以你会得到它

      ~a + a + 1 = 0
      

      那是

      ~a + 5 + 1 = 0
      

      因此表达式~a的值

      ~a = -5 -1 = -6
      

      用二进制表示(假设 int 类型占用 4 个字节)

      a ( = 5 ) = 00000000 00000000 00000000 00000101
      ~a        = 11111111 11111111 11111111 11111010
      
      a + ~a    = 11111111 11111111 11111111 11111111
      

      最后一个二进制值是-1在int类型中的表示。

      在本次通话中

      printf("%d\n",a=~a);
      

      起初,由于赋值,表达式 ~a 被截断为 unsigned char 类型的对象

      a=~a
      

      即表达式将有一个非负数。

      【讨论】:

        猜你喜欢
        • 2018-02-27
        • 1970-01-01
        • 1970-01-01
        • 2018-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-28
        相关资源
        最近更新 更多