zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    leetcode 13. Roman to Integer
    python 判断是否为有效域名
    leetcode 169. Majority Element
    leetcode 733. Flood Fill
    最大信息系数——检测变量之间非线性相关性
    leetcode 453. Minimum Moves to Equal Array Elements
    leetcode 492. Construct the Rectangle
    leetcode 598. Range Addition II
    leetcode 349. Intersection of Two Arrays
    leetcode 171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/xueda120/p/3068217.html
Copyright © 2011-2022 走看看