java按位非_Java的运算符--与(&)、非(~)、或(|)、异或(^)详解

一、计算机中存储的都是补码

java也是如此:

System.out.println(Integer.toBinaryString(2));

System.out.println(Integer.toBinaryString(-2));

运行结果:

10

11111111111111111111111111111110

由于整数默认int型,32位。正数的补码和原码都一样,高位的0默认不打印。因此是10。

-2

原码:1000 0000 0000 0000 0000 0000 0000 0010

反码:1111 1111 1111 1111 1111 1111 1111 1101 (在源码基础上符号位不变,其余位取反)

补码:1111 1111 1111 1111 1111 1111 1111 1110 (反码+1)

从上面的结论来看,java二进制数据是以补码来存储的。

二、运算也是在反码的基础上进行运算的

1. ~ 按位非(NOT)操作。每位取反。即原来是0的变成1,原来是1的变成0。

System.out.println(~ (-2)); //结果为1

分析:

step1 -> -2原码:1000 0000 0000 0000 0000 0000 0000 0010step2-> -2反码:1111 1111 1111 1111 1111 1111 1111 1101step3-> -2补码:1111 1111 1111 1111 1111 1111 1111 1110step4-> 对-2的补码进行取反即可得到~(-2)的补码

step5-> ~(-2)补码:0000 0000 0000 0000 0000 0000 0000 0001step6-> 由于符号位为0表示正数,因此补码和源码一样。转换为十进制就是1

2. & 按位与(AND)操作。1和1为1,1和0为0,0和0为0。

System.out.println(-3 & 2); //结果为0

分析:

step1 -> -3的原码:1000 0000 0000 0000 0000 0000 0000 0011step2-> -3的反码:1111 1111 1111 1111 1111 1111 1111 1100step3-> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step4-> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010step5->step3和step4进行与运算即可得-3&2的补码,结果是正数,补码和原码相同。

step6-> -3&2补码: 0000 0000 0000 0000 0000 0000 0000 0000step7-> 转换为十进制就为0

3. | 按位或(OR)操作。1和1为1,1和0为1,0和0为0。

System.out.println(-3 | 2); //结果为-1

分析:

step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step2-> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010step3->step1和step2进行或运算即可得到-3|2的补码

step4-> -3|2补码: 1111 1111 1111 1111 1111 1111 1111 1111step5->由于结果是在补码的基础上运算得来个,最高位为1表示负数,负数的补码和原码不相同,因此需要将补码转换为原码。

step6-> -3|2反码: 1111 1111 1111 1111 1111 1111 1111 1110(反码到补码是反码+1,因此补码到反码是补码-1)

step7-> -3|2原码: 1000 0000 0000 0000 0000 0000 0000 0001(符号位不变,反码取反)

step7-> 将step7的二进制转换为十进制,即为-1

4. ^ 按位异或(XOR)操作。不同为1,相同为0。1和1为0,1和0为1,0和0为0。

System.out.println(-3 ^ 2); //结果为-1

分析:

step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step2-> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010step3->step1和step2做异或运算得到补码

step4-> -3^2补码: 1111 1111 1111 1111 1111 1111 1111 1111step5->由于结果是负数,因此需要将运算得补码转换为原码。

step6-> -3^2反码: 1111 1111 1111 1111 1111 1111 1111 1110(补码-1)

step7-> -3^2原码: 1000 0000 0000 0000 0000 0000 0001 0001(符号位不变,反码取反)

step8-> 将step7的二进制原码转换为十进制数,结果为-1

5. >> 右移位操作(var >> bit)。指定值所有位向右移动指定位数。低位舍弃,高位按符号位填充。没有溢出的情况下,相当于除以2的n次方。

System.out.println(-3 >> 3); //结果为-1

分析:

step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step2->右移3位

step3-> 右移后补码:1111 1111 1111 1111 1111 1111 1111 1111step4->高位为负数因此,高位补1,低位舍弃。负数要转换为原码

step5-> 右移后反码:1111 1111 1111 1111 1111 1111 1111 1110(补码-1)

step6-> 右移后原码:1000 0000 0000 0000 0000 0000 0000 0001(符号位不变,反码取反)

step7-> step6转换为十进制值为-1

6. >>> 无符号右移位操作(var >>> bit)。指定值所有位向右移动指定位数。低位舍弃,高位补0。

System.out.println(-3 >>> 3); //结果为536870911

分析:

step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step2->无符号右移3位,高位补0,低位舍弃。

step3-> 右移后补码:0001 1111 1111 1111 1111 1111 1111 1111step4-> 正数的补码和原码一样。结果为536870911

7. << 左移位操作(var << bit)。指定值所有位向左移动指定位数。低位补0,高位保留符号位。没有溢出的情况下,相当于乘以2的n次方。

System.out.println(-3 << 3); //结果为-24

分析:

step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101step2->左移3位,高位不变。低位补0

step3-> 右移后补码:1111 1111 1111 1111 1111 1111 1110 1000step4-> 右移后反码:1111 1111 1111 1111 1111 1111 1110 0111step5-> 右移后原码:1000 0000 0000 0000 0000 0000 0001 1000step6-> 将step5转换为十进制即为-24

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值