常常会混淆移位操作的概念,因此在这里记录下测试程序。
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
// testSwitch();
testShfit();
}
/**
* 关于二进制数加减法
* 原码、反码、补码
* 正数:
* 原码就是原始数值的二进制表示形式,最高位符号位是0
* 反码是原码的按位置取反
* 补码是反码的基础上+1
*
* 负数:
* 原码就是最高位为1的表示形式
* 反码是最高位的符号位不变,其余位子按位置取反即可
* 补码是反码+1
*
* 在计算内,正数的表示为原码,负数的表现为补码,
*
* 3-3
*
* 3:
* 0011
*
* -3:
* 原码:1011
* 反码:1100
* 补码:1101
*
* 补码=反码+1
*
* 3-3== 0011
* +1101
* -----------
* 10000
* -----------------
* 这里的1是溢出位,舍弃即可,租后最后结果为0
*
* 8-8
*
* 8:
* 原码:1000
* 反码:0111
* 补码:1000
*
* -8:
* 原码:1000
* 反码:1111
* 补码:1000
*
* 说明:
* 虽然这里的-8的补码最后计算的结果为:10000,最高位的值要舍弃,变为了0000,但是由于它的最高位是1,因此符号位的最高位要填入1
* 最后变为了1000
*
* 8-8 == 1000
* +1000
* ------------
* 10000
* --------
* 最高位1舍弃,出现溢出值,最后结果为0
*
* ***/
private static void testShfit()
{
int a=-8;
log("原始值得二进制:"+Integer.toBinaryString(a));
int leftShift=a<<2;
log("逻辑左移:"+Integer.toBinaryString(leftShift));//向左边移动,右边补0,原来左边左边的值被丢弃
// int aLeftShit=a<<<2;
int rightShift=a>>2;//逻辑右移:往右边移动,原来右边的值被丢弃,左边补填充符号位,移动N,则左边补足N个符号位的值
log("逻辑右移:"+Integer.toBinaryString(rightShift));
int ARightShift=a>>>2;//算术右移 往右边移动,移动N,则原始右边丢弃N个数,但是左边移动进来的要根据原始数值的正负做判断
//如果是负数,则原始值得最高位,也就是左边的第一位是1,正数则表示左边的第一位为0,
//然后依次在左边补足N个符号位的值
/**
* :最高位符号位是0
* 8
* 二进制数表示为:1000
* 左移2位:100000
* 右移两位:0010
* 逻辑右移2位:0010
* 正数的情况下,逻辑右移和算术逻辑右移是同样的,因为都是补0的情况
* **/
/***
*负数的情况:最高位符号位是1
* 负数的情况表示二进制的话,需要使用反码表示
* 1000
* 1111
* -8
* 二进制数:1000
*
* 左移2位:0000
*逻辑右移2位:1110
* 算术逻辑右移:1110
*
* ***/
log("算术逻辑右移:"+Integer.toBinaryString(ARightShift));
}
private static void log(String msg)
{
System.out.println("INFO:"+msg);
}
}