C语言中的位操作(1)判断整数的符号

关于衡量计算操作的方法:

   当为算法统计操作的数量的时候,所有的C运算符被认为是一样的操作。中间过程不被写入随机存储器(RAM)而不被计算,当然,这种操作数的计算方法,只是作为那些接近机器指令和CPU运行时间的服务。所有的操作被假设成花相同的运行时间,事实上是不正确的。有很多不同的因素决定一个系统能多快运行一段样例代码,例如:缓存大小,内存带宽,指令集合等等……。最后,建立一套标准才是衡量一种方法快过另一种方法的最好方法。

   判断一个整数的符号

int v;      // v为我们要判断的整数
int sign;   // 保存结果 

sign = -(v < 0);   // if v < 0 sign= -1, else 0. 

//或者为了避免在cpu上判断而使用寄存器
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));  // CHAR_BIT 是每字节的位数 (通常为 8).

//或者为了减少指令(但不轻便)
sign = v >> (sizeof(int) * CHAR_BIT - 1); 

测试代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<ctype.h>
#include<limits.h>

int test(int v)
{  //正数返回0,负数返回-1
   int sign;
   sign = -(v < 0);  
   sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));  // CHAR_BIT 是每字节的位数 (通常为 8).
   sign = v >> (sizeof(int) * CHAR_BIT - 1);
    return sign;
}

int main()
{
    int v;
    scanf("%d",&v);
    printf("%d\n",test(v));
    getchar();
    getchar();
    return 0;
}

     评估一下上面最后一个语句:sign = v >> 31 for 32-bit integers,这是一个比常规操作:sign = -(v < 0).更快的方法,这种技巧可行是因为:当有符号整数右移,最左边的位被复制到其他位,最左边的位是1说明这个整数是负数,否则为0则为正数。当所有的位是1的时候返回-1,但是这种行为是面向特定的结构。

   又或者你更加喜欢返回的结果为-1或+1,于是有了下面的表达方式:

ign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1));  // 假如v < 0 返回-1, 否则返回 +1

   再或者你偏爱结果返回形式是-1,0,+1,可以使用下列表现形式:

sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

//或者速度更快,但是不轻便
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1));  // -1, 0, or +1

// 或者轻便、简洁但是也许速度不快
sign = (v > 0) - (v < 0); // -1, 0, or +1

可能你想知道数字是否非负,结果返回值为:+1或者0,于是可以使用

sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1)); // 如果 v < 0  返回 0, 否则返回 1
原文地址:https://www.cnblogs.com/xueda120/p/3068217.html