13

我希望能够访问 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,那么为什么当我移动它时会得到 -1?

4

9 回答 9

31

那这个呢?

int sign = number < 0;

于 2010-06-08T22:06:27.050 回答
16

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

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

于 2010-06-08T22:07:17.027 回答
8

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

int sign_bit = ((unsigned int)number) >> 31;
于 2010-06-08T22:08:52.727 回答
8

您可以使用 cmath 库

#include <cmath>

并像使用它一样

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

此函数将浮点值作为输入,将布尔值作为输出。

true for negative
false for positive

例如

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

会给你一个 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
于 2015-03-10T11:31:31.517 回答
4

对于整数,测试number < 0

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

于 2011-11-17T04:36:27.520 回答
3

>>运算符正在执行算术移位,它保留了数字的符号。

于 2010-06-08T22:06:26.980 回答
1
bool signbit(double x)
{
    return 1.0/x != 1.0/fabs(x);
}

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

于 2013-12-06T13:42:10.893 回答
0

您可以执行以下操作:

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

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

于 2019-08-19T11:22:48.200 回答
-1
bool signbit(double x)
{
    return (__int64)x & 0x8000000000000000LL != 0LL;
}

bool signbit(float x)
{
    return (__int32)x & 0x80000000 != 0;
}
于 2015-06-24T11:23:23.627 回答