【问题标题】:NOT operation on integer value整数值的 NOT 运算
【发布时间】:2013-07-30 22:08:52
【问题描述】:

我知道 ~ 运算符不操作。但我无法弄清楚以下程序的输出(即-65536)。到底发生了什么?

#include <stdio.h>

int main(void) {
  int  b = 0xFFFF;
  printf("%d",~b);
  return 0;
}

【问题讨论】:

  • 所以你已经知道它做了什么你的问题比
  • @suspectus 请不要将 C 标签添加到带有 C++ 标签的问题中,反之亦然。这些是不同的语言。如果您认为某个问题是 C 而不是 C++,并且被错误地标记为 C++,则应在添加 C 标记时删除 C++ 标记。
  • @aaronman 如果它不是 'b' .. 那么输出应该是 0 但为什么 -65536
  • 你的整数是有符号整数而不是无符号整数
  • 我认为您假设operator~ 是一个逻辑 NOT 操作。它实际上是一个 binary NOT 操作。大不同。

标签: c++ bit-manipulation tilde


【解决方案1】:

它正在做一个按位补码,这个输出可以帮助你更好地理解发生了什么:

std::cout <<  std::hex << " b: " << std::setfill('0') << std::setw(8) <<  b
           << " ~b: " <<  (~b) << " -65536: " << -65536 << std::endl ;

我收到的结果如下:

b: 0000ffff ~b: ffff0000 -65536: ffff0000

所以我们将低 16 位设置为1,这给了我们0000ffff,然后我们做一个补码,将低 16 位设置为0,将高 16 位设置为1,这给了我们ffff0000 等于十进制的-65536

在这种情况下,由于我们使用的是按位运算,因此检查十六进制数据可以让我们对正在发生的事情有所了解。

【讨论】:

    【解决方案2】:

    您的评论:

    如果不是 'b' .. 那么输出应该是 0 但为什么是 -65536

    表明您期待以下结果:

    uint32_t  x = 0xFFFF;
    uint32_t y = ~x;
    

    成为0

    这对于 逻辑 非操作是正确的,例如:

    uint32_t x = 0xFFFF;
    uint32_t y = !x;
    

    ...但是operator~ 不是 logical NOT,而是 bitwise not。有很大的不同。

    对于非 0 值,逻辑返回 0(或对于真值返回 false),对于 0 值返回 1。

    但是按位不会反转给定值中的每个位。所以0xF的二进制NOT:

    0x0F:  00000000 11111111
    ~0x0F: 11111111 00000000
    

    不是零,而是0xF0。

    【讨论】:

      【解决方案3】:

      对于整数中的每个二进制数,按位 NOT 运算将所有 1 变为 0,并将所有 0 变为 1。

      所以十六进制0xFFFF是二进制1111 1111 1111 1111(每个十六进制字符为4位,而F为15,四位全为1)

      你设置了一个 32 位整数,这意味着它现在是:

      0000 0000 0000 0000 1111 1111 1111 1111

      然后你不是它,这意味着它是:

      1111 1111 1111 1111 0000 0000 0000 0000

      最高位是签名位(无论是正数还是负数),所以它给出一个负数。

      【讨论】:

        【解决方案4】:

        结果取决于有符号整数在您的平台上的表示方式。最常见的表示是使用“2s 补码”算法来表示负值的 32 位值。也就是说,负值-x 由与无符号值2^32 - x 相同的位模式表示。

        在这种情况下,原始位模式设置了低 16 位:

        0x0000ffff
        

        按位取反清除这些位并设置高 16 位:

        0xffff0000
        

        将此解释为负数给出值-65536

        通常,在处理按位运算时,您会希望使用无符号类型,以避免这种混淆。

        【讨论】:

          【解决方案5】:

          假设 32 位整数

          int  b = 0xFFFF; => b = 0x0000FFFF
          ~b = 0xFFFF0000
          

          现在设置了最高位。假设2s complement,这意味着我们有一个负数。反转其他位然后加一个得到0x0001000065536

          【讨论】:

            【解决方案6】:

            当您将 16 位值 0xffff 分配给 32 位整数 b 时,变量 b 实际上变为 0x0000ffff。这意味着当您执行 按位补码 时,它变为 0xffff0000,与十进制 -65536 相同。

            【讨论】:

              【解决方案7】:

              C++ 中的 ~ 运算符是按位 NOT 运算符。它也称为按位补码。这是翻转您的 signed 整数的位。

              例如,如果你有

               int b = 8;
               // b in binary = 1000
               // ~b = 0111
              

              这将翻转表示提供的初始整数值的位。

              【讨论】:

              • ~b = 0111 仅当 int 为 4 位时。它很可能是 1111111111110111 二进制,假设 32 位整数
              • 对,但他没有提供有关架构的任何信息
              猜你喜欢
              • 2017-10-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-22
              • 2020-08-09
              相关资源
              最近更新 更多