/*
* JAVA位运算: 与(&)、非(~)、或(|)、异或(^)、左移(<<)、右移(>>)
*+-----------------------------------------------------------------------------------+
*| & | 当两边操作数的位同时为1时,结果为1,否则为0 如1 1 0 0 & 1 0 1 0 = 1 0 0 0 |
*+-----------------------------------------------------------------------------------+
*| | | 当两边操作数的位有一边为1时,结果为1,否则为0 如1 1 0 0 | 1 0 1 0 = 1 1 1 0 |
*+-----------------------------------------------------------------------------------+
*| ~ | 将操作数的位0变1,1变0。如 ~1 1 0 0 = 0 0 1 1 |
*+-----------------------------------------------------------------------------------+
*| ^ | 当两边操作数的位相同时,结果为0,否者为1。如1 1 0 0 ^ 1 0 1 0 = 0 1 1 0 |
*+-----------------------------------------------------------------------------------+
*| << | 将操作数按位左移m位,如 int 1 << 2, 0000 0000 0000 0000 0000 0000 0000 0001 |
*| | << 2 = 0000 0000 0000 0000 0000 0000 0000 0100 = 4 |
*+-----------------------------------------------------------------------------------+
*| >> | 将操作数按位右移m位,如 int 4 >> 2, 0000 0000 0000 0000 0000 0000 0000 0100 |
*| | >> 2 = 0000 0000 0000 0000 0000 0000 0000 0001 = 1 |
*+-----------------------------------------------------------------------------------+
*| >>> | 无符号右移操作不考虑符号位,最右边数据位丢失,最左边数据位用0填充 |
*| | 1111 1111 1111 1111 1111 1111 1111 0110 (-10) >>> 1 = |
*| | 0111 1111 1111 1111 1111 1111 1111 1011 (2147483643) |
*+-----------------------------------------------------------------------------------+
*==========================================================================================================
*<< 运算规则:
*1.按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零;
*2.当左移的运算数是int类型时,每移动1位它的第31位就要被移出并且丢弃;
*3.当左移的运算数是long类型时,每移动1位它的第63位就要被移出并且丢弃;
*4.当左移的运算数是byte和short类型时,将自动把这些类型扩大为 int型;
*
*<< 数学意义:
*1.数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
*
*<< 注意事项:
*1.如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了33%32=1位
*2.n位二进制,最高位为符号位,因此表示的数值范围-2^(n-1) -- 2^(n-1) -1,所以模为2^(n-1)
*===========================================================================================================
*>> 运算规则:
*1.按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1
*2.当右移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型
*例如:如果要移位值为负数,每一次右移都在左边补1,如果要移位值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位),在进行右移
*
*>> 数学意义
*1.右移一位相当于除2,右移n位相当于除以2的n次方
*
*>> 注意事项:
*1.符号位不变,左边补上符号位
*===========================================================================================================
*>>>
*1.忽略了符号位扩展,0补最高位
*2.无符号右移运算符>>> 只是对32位和64位的值有意义
*===========================================================================================================
*负数以其正值的补码形式表示
*补码 = 原码的反码 + 1
*反码 = 原码按位取反
*原码 = 数字的二进制表示
*
*在密码运算和图形操作中,位移操作才会被经常用到。只有在需要特别快的性能,并且性能测试证明数学
*运算导致了性能问题的情况下,才使用位移操作。
*===========================================================================================================
* 1 << 2 = 0000 0000 0000 0000 0000 0000 0000 0001 << 2 = 0000 0000 0000 0000 0000 0000 0000 0100 [4]
* 1 << -2 = 0000 0000 0000 0000 0000 0000 0000 0001 << -2 = 0000 0000 0000 0000 0000 0000 0000 0100 [1073741824] == [1 << 32 + (-2)]
* 1 << 31 = 0000 0000 0000 0000 0000 0000 0000 0001 << 31 = 1000 0000 0000 0000 0000 0000 0000 0000 [-2147483648] == [-2^31]
* -1 << 2 = 1111 1111 1111 1111 1111 1111 1111 1111 << 2 = 1111 1111 1111 1111 1111 1111 1111 1100 [-4]
*-2^31 << 2 = 1000 0000 0000 0000 0000 0000 0000 0000 << 2 = 0000 0000 0000 0000 0000 0000 0000 0000 [0]
*-2^31 >> 2 = 1000 0000 0000 0000 0000 0000 0000 0000 << 2 = 1110 0000 0000 0000 0000 0000 0000 0000 [-536870912]
*-2^31 >>> 2 = 1000 0000 0000 0000 0000 0000 0000 0000 << 2 = 0010 0000 0000 0000 0000 0000 0000 0000 [536870912]
*===========================================================================================================
*/