zoukankan      html  css  js  c++  java
  • 位运算及移位,反码,补码

    反码,补码

    将正数各个位取反,1变为0,0变为1所得二进制位反码,将反码+1所得到的二进制数为补码,补码为该正数在计算机中存储的负数形式,如,4在int类型占用4个字节32位,其原码,反码及补码如下

    原码:00000000 00000000 00000000 00000100
    反码:  11111111 11111111 11111111 11111011
    补码: 11111111 11111111 11111111 11111100  (-4在计算机中的表示形式)

    通过代码验证-4的二进制形式与上述补码一致

    String binaryString = Integer.toBinaryString(-4);
    System.out.println(binaryString);

    无符号整数与有符号整数

    无符号整数的所有位均表示数字,有符号整数的最高位表示符号,1表示负数,0表示正数。

    对于byte,无符号时最小值为00000000=0,最大值为11111111=2^7+2^6+ ... 2^0=255,包含256个数字,有符号时,最小值为10000000=-2^7=-128,最大值为01111111=2^6+2^5+ ... 2^ 0=127

    位运算

    & 按位与,全为1时为1,否则为0

    |  按位或,全为0时为0,否则为1

    ~ 按位非,0求非为1,1求非为0

    ^ 按位异或,相同为0,不同为1

    示例(某些示例只显示的计算位,准确应该是32位,且以下示例也都可以通过java代码来验证结果是否正确)

    1、& 按位与,全为1时为1,否则为0

    3 & 5 = 0011 & 0101 = 0001 = 1
    6 & 5 = 0110 & 0101 = 0100 = 4
    7 & 5 = 0111 & 0101 = 0101 = 5

    2、| 按位或,全为0时为0,否则为1

    3 | 5 = 0011 | 0101 = 0111 = 7
    6 | 5 = 0110 | 0101 = 0111 = 7
    7 | 5 = 0111 | 0101 = 0111 = 7

    3、~ 按位非,0求非为1,1求非为0

    ~ 2 = ~ 00000000 00000000 00000000 00000010 = 11111111 11111111 11111111 11111101

    这是一个负数,不好直接计算,正数的负数形式是先反码然后+1得到反码即为该正数的负数形式,反过来,负数获取其对应正数,先-1,然后反码

    ~2-1 = 11111111 11111111 11111111 11111100

    取反

    00000000 00000000 00000000 00000011 = 3

    所以~2 = -3

    同理可得到~3=-4

    4、^ 按位异或,相同为0,不同为1

    2 ^ 3 = 0010 ^ 0011 = 0001 = 1
    3 ^ 3 = 0011 ^ 0011 = 0000 = 0 
    4 ^ 7 = 0100 ^ 0111 = 0011 = 3

    移位

    1、左移,高位移除,低位补0

    2 << 3 = 0010 << 3 = 0010 000 = 2^4=16

    左移一位,相当于乘以2,左移n位,相当于乘以2的n次方

    对于int类型,当移动超过了32为,相当于移动了movenNum%32位

    对于long类型,若移动超过64位,相当于移动了moveNum%64位

    byte和short类型,自动把这些类型扩大为int

    2、右移,符号位不变,低位移除,高位补符号位

    2 >> 2 = 0010 >>2 = 0000=0

    右移一位,相当于除以2,左移n为,相当于除以2的n次方,但当移位之后的数值小于1时,实际移位得到的值为0,如上述2 >> 2,2 /2/2=0.5<1,最后结果为0

    3、无符号右移,低位移除,高位补0

    对于正数的无符号右移,与有符号右移得出的结果一样

    System.out.println(8 >>> 2); // 2
    System.out.println(8 >> 2); // 2

    负数的无符号右移与有符号右移得出结果不同

    /*
             * 1的原码,反码及补码如下
             * 原码:00000000 00000000 00000000 00000001
             * 反码:11111111 11111111 11111111 11111110
             * 补码:11111111 11111111 11111111 11111111 (-1)
             * 
             * 11111111 11111111 11111111 11111111 
             * 有符号右移两位,低位1去掉,高位补1,最后二进制码跟之前一样,结果还是-1
             * 11111111 11111111 11111111 11111111 
             * 无符号右移2为得到00111111 11111111 11111111 11111111
             * 该值通过2^29+2^28+ ... 2^0计算得出结果为1073741823
             */
            System.out.println(-1>>2); // -1
            System.out.println(-1>>>2); // 1073741823

     4、不存在无符号左移,因为左移时,低位补0,高位直接舍弃,不需要对符号位添加1或者0操作,在java代码中,如下写法会出现编译错误

  • 相关阅读:
    https://vjudge.net/problem/计蒜客-44317/origin
    zsh终端配置环境变量:
    python库路径问题
    pandas 常用API
    https://codeforces.com/contest/1301/problem/B
    vue中8种组件通信方式, 值得收藏!
    让你减少加班的15条高效JS技巧!记得收藏哦
    那个炒鸡有趣的HTML5标签 —— <dataList>
    前端面试之浏览器/HTML/CSS问题
    插件界的瑞士军刀,vs code已经无所不能!
  • 原文地址:https://www.cnblogs.com/qq931399960/p/10795133.html
Copyright © 2011-2022 走看看