Java逻辑运算符

个人理解,仅供参考。

机器数和真值

1.机器数

  一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号位的,在计算机中用一个数的最高位存放符号位,正数为0,负数为1。

@Test
	public void test() {
		int a = 5;
		int b = -5;
		System.out.println("5对应的二进制数:" + Integer.toBinaryString(a));
		System.out.println("-5对应的二进制数:" + Integer.toBinaryString(b));
	}


PS:5对应的二进制数应该是 00000000 00000000 00000000 00000101

2.真值

  由于第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的二进制数,呃,太长算不了。

  为了方便计算,我们假设计算机字长为8位,所以:

  +5 ---- 0000 0101

  -5 ---- 1111 1011

  假设不考虑符号位 那么1111 1011计算出来的结果是251。为了区别将带符号位的机器数对应的真正数值称为机器数的真值。

原码 反码 补码

1.正码

  原码就是符号位位加上真值得绝对值,第一位使用符号位,其余位表示数值。例如8bit二进制:

  [+1]原 = 0000 0001

  [-1]原 = 1000 0001

  取值范围为[1111 1111,0111 1111] 即 [-127,127]

2.反码

  正数的反码是其本身。

  负数的反码就是其原码的基础上,符号位不变,其余的位取反。

  [+1] = [0000 0001]原 = [0000 0001]反

  [-1] = [1000 0001]原 = [1111 1110]反

3.补码

  正数的补码还是它自己。

  负数的补码是在其原码的基础上,符号位不变,其余各位取反。或者说在其反码的基础上+1。

  [+1] = [0000 0001]原 = [0000 0001]反 = [0000 0001]补

  [-1] = [1000 0001]原 = [1111 1110]反 = [1111 1111]补

为何使用原码 反码 补码

  运算法则:减去一个正数等于加上一个负数。

  那么问题来了:

1.计算十进制的表达式:1 - 1 = 0

  1 - 1 = 1 + (-1)

        = [0000 0001]原 + [1000 0001]原

        = [1000 0000]原 = -2

  错误的结果。。。

2.使用反码

  1 - 1 = 1 + (-1)

        = [0000 0001]原 + [1000 0001]原

        = [0000 0001]反 + [1111 1110]反

        = [1111 1111]反

        = [1000 0000]原 = -0

  [1000 0000]原 ---- -0

  [0000 0000]原 ---- +0

3.使用补码

  1 - 1 = 1 + (-1)

        = [0000 0001]原 + [1000 0001]原

        = [0000 0001]补 + [1111 1111]补

        = [0000 0000]补

  (-1) + (-127) = [1000 0001]原 + [1111 1111]原

                   = [1111 1111]补 + [1000 0001]补

                   = [1000 0000]补

  -128的补码[1000 0000]补,也就是使用-0的补码表示。但是-128并没有原码和反码。

  对[1000 0000]补求其原码得出  [0000 0000]原是错误的。

  解决0的符号问题。

移位运算符 >> >>> <<

1.>> 带符号右移

  将二进制向右移动n位,在丢失的位置补上符号位

2.>>> 无符号右移

  将二进制向右移动n位,在丢失的位上补上0

3.<< 左移

  将二进制向左移动n位,在丢失的位上补上0

     @Test
	public void test() {
		int a = 15;
		int b = -15;
		System.out.println(Integer.toBinaryString(a)) ;
		System.out.println("5 >> 3 :" + Integer.toBinaryString(a >> 3));
		System.out.println("5 >>> 3 :" + Integer.toBinaryString(a >>> 3));
		System.out.println("5 << 3 :" + Integer.toBinaryString(a << 3));
		System.out.println(Integer.toBinaryString(b)) ;
		System.out.println("-5 >> 3 :" + Integer.toBinaryString(b >> 3));
		System.out.println("-5 >> 3 :" + Integer.toBinaryString(b >>> 3));
		System.out.println("-5 >> 3 :" + Integer.toBinaryString(b << 3));</span>
	}


位运算符 & | ^  ~

& 全1才1

~ 按位取反

| 有1就1

^ 相同为0 不同为1


@Test
	public void test() {
		int a = 15;
		int b = -15;
		System.out.println(Integer.toBinaryString(a)) ;
		System.out.println(Integer.toBinaryString(b)) ;
		System.out.println("a | b :" + Integer.toBinaryString(a | b));
		System.out.println("a & b :" + Integer.toBinaryString(a & b));
		System.out.println("a ^ b :" + Integer.toBinaryString(a ^ b));
		System.out.println("~a :" + Integer.toBinaryString(~a));
	}
 

PS:

1.一个数的补码的补码是其原码。

2.一个数异或一个数两次还是等于它本身。 a^b^b = a

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值