美文网首页
位运算与移位运算

位运算与移位运算

作者: 泡泡茶壶大人 | 来源:发表于2020-09-21 17:16 被阅读0次

    原码、反码、补码

    对于有符号的数来说:

    1. 二进制的最高位是符号位:0表示正数,1表示负数;

    示例:

    1-1byte (8位) 类型再内存中分别表示为:

    1 ==> [0000 0001] -1 ==> [1000 0001]

    1. 正数的原码、反码、补码都一样;
    2. 负数的反码 = 原符号位不变,其他位取反 (0->1 1->0)
    3. 负数的补码 = 反码 + 1
    4. 0的原码、反码、补码都是0
    5. 在计算机运算时,都是以补码的方式运算的

    示例:

    10: 8位原码、反码、补码: 0000 1010
    6:  8位原码、反码、补码:0000 0110
    -6:  8位原码:1000 0110  反码:1111 1001  补码:1111 1010
    -10: 8位原码:1000 1010  反码:1111 0101  补码:1111 0110
    

    位运算符

    按位与 (&): 两位全为1,结果为1,否则为0

    示例:

    计算 10 & -6
    10的补码:0000 1010
    -6的补码:1111 1010
    ----------------------
    结果补码: 0000 1010 ==> 正数,即为 10
    
    计算 -10 & -6
    -10的补码:1111 0110
    -6的补码: 1111 1010
    ----------------------
    结果补码: 1111 0010 ==> 反码:1111 0001 ==> 原码:1000 1110 即 -14
    

    按位或 (|): 两位只要有一个为1,结果为1,均为不1,即为0

    示例:

    计算 10 | 6
    10的补码:0000 1010
    6的补码: 0000 0110
    -----------------------
    结果补码:0000 1110 ==> 正数,即为 14
    
    计算 10 | -6
    10的补码:0000 1010
    -6的补码:1111 1010
    -----------------------
    结果补码:1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6
    

    按位异或 (^): 只有当两位不相同时,结果为1,否则为0

    示例:

    计算 10 ^ 6
    10的补码:0000 1010
    6的补码: 0000 0110
    -----------------------
    结果补码:0000 1100 ==> 正数,即为 12
    
    计算 10 ^ -6
    10的补码:0000 1010
    -6的补码:1111 1010
    -----------------------
    结果补码:1111 0000 ==> 反码:1110 1111 ==> 原码:1001 0000 即 -16
    

    任何数与0异或,结果都是其本身。

    利用异或还可以实现两个数的交换:

    int a = 10;
    int b = -6;
    a = a ^ b; //生成补码: 1111 0000
    b = a ^ b; //生成补码: 0000 1010 ==> 10
    a = a ^ b; //生成补码: 1111 1010 ==> 原: 1000 0110 即-6
    //以上通过按位异或,实现a、b两个数的交换。
    
    //交换方法二: (补充)
    a = a + b;
    b = a - b;
    a = a - b;
    

    非(~): 按位取反,包括符号位

    计算 ~10
    10的补码:0000 1010
    -----------------------
    结果补码:1111 0101 ==> 反码:1111 0100 ==> 原码:1000 1011 即 -11
    
    计算 ~-6
    -6的补码:1111 1010
    -----------------------
    结果补码:0000 0101 ==> 正数,即 5
    

    移位运算符

    右移:低位溢出,符号位不变,并用符号位补溢出的高位

    符号:>>

    /* 位右移:
     * 右移一位,相当于原数值 / 2,
     * 右移两位,相当于原数值 / 4,
     * 右移n位,相当于原数值 / 2^n
     * 结果没有小数(向下取整)
     */
    计算 10 >> 1
    10的补码:0000 1010
    -----------------------
    结果补码:0000 0101 ==> 正数,即 5
    
    计算 10 >> 2
    10的补码:0000 1010
    -----------------------
    结果补码:0000 0010 ==> 正数,即 2
    
    计算 11 >> 1
    11的补码:0000 1011
    -----------------------
    结果补码:0000 0101 ==> 正数,即 5
    
    计算 -11 >> 1
    -11的补码:1111 0101
    -----------------------
    结果补码: 1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6
    

    左移:符号位不变,低位补0

    符号:<<

    /* 位左移:
     * 左移一位,相当于原数值 * 2,
     * 左移两位,相当于原数值 * 4,
     * 左移n位,相当于原数值 * 2^n
     */
    计算 10 << 1
    10的补码:0000 1010
    -----------------------
    结果补码:0001 0100 ==> 正数,即 20
    
    计算 10 << 2
    10的补码:0000 1010
    -----------------------
    结果补码:0010 1000 ==> 正数,即 40
    
    计算 11 << 1
    10的补码:0000 1011
    -----------------------
    结果补码:0001 0110 ==> 正数,即 22
    
    计算 -11 << 1
    -11的补码:1111 0101
    -----------------------
    结果补码: 1110 1010 ==> 反码:1110 1001 ==> 原码:1001 0110 即-22
    

    参考文章:
    https://www.jianshu.com/p/c6362f67ef5b
    https://www.jianshu.com/p/60952a44841f

    相关文章

      网友评论

          本文标题:位运算与移位运算

          本文链接:https://www.haomeiwen.com/subject/aqavyktx.html