/* * 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] *=========================================================================================================== */