zoukankan      html  css  js  c++  java
  • 用位运算求一个数的绝对值

         我们知道在我们对一个数进行位运算的时候,是在这个数的补码上进行的,对于补码我们知道,正数的补码是原码,负数的补码为原码除了最高位的符号位,取反,然后加1。把补码转换成原码的时候,正数还是原码,负数时把补码除了符号位取反然后加1(我们可以发现如果这时候连符号位也求反,然后加1,与以前不同的只是少了一个符号位,现在实际上就是这个数的绝对值)。所以我们可以得到对一个负数求绝对值的表达式为

    1. int SignReversal(int a)  
    2. {  
    3.     return ~a + 1;  
    4. }

    那么由这些知识我们可以很快地得到求一个数的绝对值的表达式:

    先移位来取符号位,int i = a >> 31;要注意如果a为正数,i等于0,为负数,i等于-1。然后对i进行判断——如果i等于0,直接返回。否之,返回~a+1。完整代码如下:

    [cpp] view plaincopy
     
    1. //by MoreWindows( http://blog.csdn.net/MoreWindows )  
    2. int my_abs(int a)  
    3. {  
    4.     int i = a >> 31;  
    5.     return i == 0 ? a : (~a + 1);  
    6. }  

    现在再分析下。对于任何数,与0异或都会保持不变,与-1即0xFFFFFFFF异或就相当于取反。因此,a与i异或后再减i(因为i为0或-1,所以减i即是要么加0要么加1)也可以得到绝对值。所以可以对上面代码优化下:

    [cpp] view plaincopy
     
    1. //by MoreWindows( http://blog.csdn.net/MoreWindows )  
    2. int my_abs(int a)  
    3. {  
    4.     int i = a >> 31;  
    5.     return ((a ^ i) - i);  
    6. }  

    而且有些笔面试题就要求这样做(比如不让用if语句的时候),因此建议读者记住该方法

  • 相关阅读:
    TiDB基本简介
    flink双流join
    Kafka客户端内存缓冲GC处理机制--客户端内存
    shell常用命令大全[bigdata版]
    kafka channel的parseAsFlumeEvent解析event
    hdfs的写流程以及namenode,datanode挂掉后处理
    [转载]LSM树由来、设计思想以及应用到HBase的索引
    HBase之写流程与读流程
    HBase之写流程中的刷写时机
    HBase之读写流程中WAL机制
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3236802.html
Copyright © 2011-2022 走看看