java位运算

位运算到底有什么用途呢?

 可以优化代码,比一般的运算要快。

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

& 按位与,可以将结果范围限制在 右边数据的范围内(例:n&5,无论n为多少,结果都在0~5范围内)

1. 原码、反码、补码

  •  原码

十进制数字的二进制表现形式就是原码

例如: 20 -> 0 0 0 1 0 1 0 0

左边第一位为符号位(0为正,1为负),其他位为数据位。

一个 byte 有 8bit,最大值是 0 1 1 1 1 1 1 1 (+127),最小值是 1 1 1 1 1 1 1 1 (-127)

  • 反码

正数的反码是它本身,负数的反码除了符号位不变,其余数据位取反

十进制数字原码反码
+00000000000000000
-11000000111111110
-21000001011111101
  • 补码

正数的补码是它本身,负数的补码等于其反码+1,

十进制数字原码反码补码
+0000000000000000000000000
-1100000011111111011111111
-2 100000101111110111111110

2. 位运算

在java当中拿int类型来说,占4个字节,32位,也就是 0000 0000 0000 0000 0000 0000 0000 0000。

位运算都是通过补码来运算,得出的结果也是补码,所以最后还需还原成原码

运算符含义运算规则
&逻辑与两个都为1时,结果才为1。
|逻辑或两个当中只要有一个为1,结果就为1
~按位取反0变1,1变0
^按位异或相同为0,相异为1
<<左移向左移动,低位补零
>>右移向右移动,高位补零,符号位按照原来数字的符号位不变
>>>无符号右移向右移动,高位补零

  • 运算符 &

都为正数的情况下,在java中,如果左边的数比右边小,那么结果就是左边的数;左边的数比右边大,那么结果就是左边数除以右边数求余再减一。

5 & 3

/**
         * 5 & 3
         * 5 补码:0000 0000 0000 0000 0000 0000 0000 0101
         * 3 补码:0000 0000 0000 0000 0000 0000 0000 0011
         * 比较值:0000 0000 0000 0000 0000 0000 0000 0001
         * 打印-结果: 1
         * 计算规则:第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0
         **/
  • 运算符 |
/**
         * 5 | 3
         * 5 补码:0000 0000 0000 0000 0000 0000 0000 0101
         * 3 补码:0000 0000 0000 0000 0000 0000 0000 0011
         *   结果:0000 0000 0000 0000 0000 0000 0000 0111
         * 打印-结果:7
         * 计算规则:第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0
         **/
  •  运算符 ~
println("~5",~5);
        /**
         * 5 补码:0000 0000 0000 0000 0000 0000 0000 0101
         *   取非:1111 1111 1111 1111 1111 1111 1111 1010 (即补码)
         *   反码:1111 1111 1111 1111 1111 1111 1111 1001
         *   原码:1000 0000 0000 0000 0000 0000 0000 0110
         *   打印-结果:-6
         *   计算规则:操作数的第n位为1,那么结果的第n位为0,反之。
         **/
  • 运算符^
println("5 ^ 3",5 ^ 3);
        /**
         * 5 | 3
         * 5 补码:0000 0000 0000 0000 0000 0000 0000 0101
         * 3 补码:0000 0000 0000 0000 0000 0000 0000 0011
         *   结果:0000 0000 0000 0000 0000 0000 0000 0110
         * 打印-结果:6
         * 计算规则:第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0
         **/
  • 左移 <<

若<<右边数字为3,就是在补码后面添加3个0,在补码最左边三位数去掉

println("5<<2", 5<<2);
        /**
         * 5<<2
         * 原码:0000 0000 0000 0000 0000 0000 0000 0101
         * 反码:0000 0000 0000 0000 0000 0000 0000 0101
         * 补码:0000 0000 0000 0000 0000 0000 0000 0101
         * 左移:0000 0000 0000 0000 0000 0000 0001 0100 
         * 补码:0000 0000 0000 0000 0000 0000 0001 0100
         * 反码:0000 0000 0000 0000 0000 0000 0001 0100
         * 原码:0000 0000 0000 0000 0000 0000 0001 0100
         * 打印-结果:20
         * 计算规则:1、向左移动指定位,左边二进制位丢弃,右边补0。(注意byte和short类型移位运算时会变成int型,结果要强制转换)
         *           2、若1被移位到最左侧,则变成负数。
         *           3、左移时舍弃位不包含1,则左移一次,相当于乘2。
         **/
  • 右移 >>
println("5>>2", 5>>2);
        /**
         * 5>>2
         * 原码:0000 0000 0000 0000 0000 0000 0000 0101
         * 补码:0000 0000 0000 0000 0000 0000 0000 0101
         * 反码:0000 0000 0000 0000 0000 0000 0000 0101
         * 右移:0000 0000 0000 0000 0000 0000 0000 0001 
         * 补码:0000 0000 0000 0000 0000 0000 0000 0001
         * 反码:0000 0000 0000 0000 0000 0000 0000 0001
         * 原码:0000 0000 0000 0000 0000 0000 0000 0001
         * 打印-结果:1
         * 计算规则:1、数值value向右移动num位,正数左补0,负数左补1,右边舍弃。(即保留符号位)
         *         2、右移一次,相当于除以2,并舍弃余数。
         **/
  • 无符号右移

就是符号位不进行移动

println("-5>>>3",-5>>>3);
        /**
         * -5>>>3
         * 原码:1000 0000 0000 0000 0000 0000 0000 0101
         * 反码:1111 1111 1111 1111 1111 1111 1111 1010
         * 补码:1111 1111 1111 1111 1111 1111 1111 1011
         * 右移:0001 1111 1111 1111 1111 1111 1111 1111 (即补码)
         * 补码:0001 1111 1111 1111 1111 1111 1111 1111
         * 反码:0001 1111 1111 1111 1111 1111 1111 1111
         * 原码:0001 1111 1111 1111 1111 1111 1111 1111
         * 打印-结果:536870911
         * 计算规则:1、数值value向右移动num位,正数左补0,负数左补1,右边舍弃。(即保留符号位)
         *         2、右移一次,相当于除以2,并舍弃余数。
         *         3、无符号右移>>>:左边位用0补充,右边丢弃。
         *         所得结果永远正数
         **/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值