首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >位运算-指示有符号整数的符号

位运算-指示有符号整数的符号
EN

Stack Overflow用户
提问于 2013-04-22 22:09:39
回答 2查看 145关注 0票数 0

为什么下面的C代码不能为负数返回-1,为0返回0,为正数返回1?

代码语言:javascript
复制
(((x >> 31) ^ -1) + 1) | (!x ^ 1);

具体地说,当我传入负数时,它返回1。似乎如果我有一个负数(即31位移位后最低有效位是1),用-1 XORing它将得到-2 (即所有1和最低有效位位置的0),加1将使其为-1。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-22 23:02:01

根据C99标准,如果x为负,则x >> n的结果是由实现定义的。所以你有问题的原因取决于你的编译器和架构。

然而,最有可能的是,当你移位x时,它是符号扩展的,也就是说,最高位被重复以保持符号与操作数相同。这就是我的编译器所发生的事情。所以对于任何负数,x >> 31都是-1。另外,对于任何非零数,!x都是0(即false)。假设x是32位整数,这是适用的。如果您将x设为无符号整型,则它应该可以工作,但请考虑以下替代方案:

代码语言:javascript
复制
(x < 0) ? -1 : ((x > 0) ? 1 : 0)

我认为这不是那么神秘。

这是一个程序,您可以使用它来查看您的表达式正在做什么

代码语言:javascript
复制
#include <stdio.h>
#define EVALUATE(x)     printf("%s = %d\n", #x, x)
int main(int argc, char** argv)
{
    unsigned        int x = 51;

    EVALUATE(x >> 31);
    EVALUATE(((x >> 31) ^ -1));
    EVALUATE(((x >> 31) ^ -1) + 1);
    EVALUATE(!x);
    EVALUATE(!x ^ 1);
    EVALUATE((((x >> 31) ^ -1) + 1) | (!x ^ 1));
    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2013-04-22 22:16:02

>>通常会对带符号的数据进行算术移位,所以((-1) >> 31) == (-1),与您的假设相反。正如其他人指出的那样,该标准不能保证这一点,但在现代系统中很可能是这样的。在任何情况下,都要小心这种类型的位摆动。如果可移植性是一个问题,或者速度不是问题,那么您应该用不同的方式来完成它。有关一些想法,请参阅Is there a standard sign function (signum, sgn) in C/C++?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16149277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档