Java逻辑运算符

来源:互联网 发布:湘潭湖南软件职业学院 编辑:程序博客网 时间:2024/06/09 15:24

个人理解,仅供参考。

机器数和真值

1.机器数

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

@Testpublic 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

     @Testpublic 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


@Testpublic 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

 

 

0 1
原创粉丝点击