【问题标题】:How can I access the sign bit of a number in C++?如何在 C++ 中访问数字的符号位?
【发布时间】:2010-06-08 22:04:05
【问题描述】:

我希望能够在 C++ 中访问数字的符号位。我当前的代码如下所示:

int sign bit = number >> 31;

这似乎有效,给我0 为正数和-1 为负数。但是,我看不出我如何得到 -1 的负数:如果 12 是

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100

那么 -12 是

1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0011

并将其移动 31 位将使

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001

这是 1,而不是 -1,那么为什么我在 shift 时会得到 -1?

【问题讨论】:

标签: c++ binary bitwise-operators


【解决方案1】:

这个怎么样?

int sign = number < 0;

【讨论】:

    【解决方案2】:

    在 C++ 中右移负数的结果是实现定义的。所以,没有人知道你的-12 应该在你的特定平台上得到什么右移。你认为它应该做到以上(1),而我说它可以很容易地产生全一模式,即-1。后者称为符号扩展移位。在符号扩展移位中,符号位被复制到右边,但永远不会移出它的位置。

    如果您只对符号位的值感兴趣,那么不要再浪费时间尝试使用按位运算,例如移位等。只需将您的数字与 0 进行比较,看看它是否为负数。

    【讨论】:

    • 这是一个非常老的帖子,但我只是在寻找其他内容时看到了这个。我基本上同意你在这里所说的。但是他在他的问题中做出了一些假设,这些假设可能有助于他的代码的结果。这可以使用位移位或仅使用位掩码检查符号位来独立完成。
    • 这不能区分 -0.0 和 +0.0。您需要为此访问符号位。请参阅约翰的回答。
    • @NeilG 根据问题中的文字,在我看来是在询问整数。
    • @m.m 哦!!我被其他答案愚弄了,没有仔细阅读。
    • 我意识到这是一个老话题,但后一种情况可以通过按位 & 1 来避免吗?
    【解决方案3】:

    因为您正在移动有符号整数。将整数转换为无符号:

    int sign_bit = ((unsigned int)number) >> 31;
    

    【讨论】:

      【解决方案4】:

      你可以使用 cmath 库

      #include <cmath>
      

      并像使用它

      std::cout << std::signbit(num);
      

      这个函数得到一个浮点值作为输入,一个布尔值作为输出。

      true for negative
      false for positive
      

      例如

      std::cout

      会给你一个 0 作为输出(假)

      但是在使用这个功能时你必须小心零

      std::cout << std::signbit(-0.0);  // 512 (true)
      std::cout << std::signbit(+0.0);  // 0   (false)
      

      这几行的输出不一样。

      要消除此问题,您可以使用:

      float x = +0.01;
      std::cout << (x >= 0 ? (x == 0 ? 0 : 1) : -1);
      

      给:

       0 for 0
       1 for positive
      -1 for negative
      

      【讨论】:

        【解决方案5】:

        对于整数,测试number &lt; 0

        对于浮点数,您可能还需要考虑零有符号这一事实。也就是说,存在一个与+0.0 不同的-0.0。为了区分这两者,你想使用std::signbit

        【讨论】:

          【解决方案6】:

          &gt;&gt; 运算符正在执行 arithmetic shift,它保留了数字的符号。

          【讨论】:

          • 没有。 &gt;&gt; 操作符执行什么样的移位是实现定义的。可以是任何类型的转变。
          • @AndreyT:我说“&gt;&gt; 运算符正在执行算术移位”,从 OP 的描述来看,这正是它在这种情况下所做的事情。请注意,我没有说“&gt;&gt; 运算符总是执行算术移位”或类似的东西。也许我应该更明确一点,但不管怎样,我认为我的回答不值得一票否决。
          • @Downvoters:请为自己辩护。我确切地解释了 OP 的问题是什么。我没有提出任何广泛的主张,例如“&gt;&gt; 运算符总是执行算术移位”;我确切地解释了&gt;&gt; 运算符在在这种特殊情况下所做的事情。
          【解决方案7】:
          bool signbit(double x)
          {
              return 1.0/x != 1.0/fabs(x);
          }
          

          我的解决方案支持 +/-0。

          【讨论】:

            【解决方案8】:

            您可以执行以下操作:

            int t1 = -12;
            unsigned int t2 = t1;
            t2 = t2>>31;
            cout<<t2;
            

            这适用于所有 c++ 实现。

            【讨论】:

              【解决方案9】:
              bool signbit(double x)
              {
                  return (__int64)x & 0x8000000000000000LL != 0LL;
              }
              
              bool signbit(float x)
              {
                  return (__int32)x & 0x80000000 != 0;
              }
              

              【讨论】:

              • 如果x 超出__int64 的范围会导致未定义的行为
              猜你喜欢
              • 2021-08-01
              • 1970-01-01
              • 2023-03-16
              • 1970-01-01
              • 1970-01-01
              • 2013-10-17
              • 2012-08-28
              • 1970-01-01
              • 2015-03-26
              相关资源
              最近更新 更多