package ssss;
public class dwd {
public static void main(String[] args) {
// 看二进制表示,最高位是1就是负数,值0就是正数。
System.out.println("------负数左移------------------------------------------------------");
int i = -6; // 负数左移
System.out.println(Integer.toBinaryString((int) i));
// 正6: 0000-0000 0000-0000 0000-0000 0000-0110
// 取反:1111-1111 1111-1111 1111-1111 1111-1001
// 加一 补码:1111-1111 1111-1111 1111-1111 1111-1010
System.out.println(Integer.toBinaryString((int) (i << 28)));
// 补码:1010-0000 0000-0000 0000-0000 0000-0000
// 减一:1001-1111 1111-1111 1111-1111 1111-1111
// 取反:0110-0000 0000-0000 0000-0000 0000-0000 -(2^29+2^30)=-1610612736
System.out.println((int) (i << 28));
System.out.println(Integer.toBinaryString((int) (i << 29)));
// 补码:0100-0000 0000-0000 0000-0000 0000-0000
System.out.println((int) (i << 29));// 2^30=1073741824
System.out.println("------正数左移------------------------------------------------------");
int j = 6; // 正数左移
System.out.println(Integer.toBinaryString((int) j));
// 正6 补码: 0000-0000 0000-0000 0000-0000 0000-0110
System.out.println(Integer.toBinaryString((int) (j << 28)));
// 补码:0110-0000 0000-0000 0000-0000 0000-0000 (2^29+2^30)=1610612736
System.out.println((int) (j << 28));
System.out.println(Integer.toBinaryString((int) (j << 29)));
// 补码:1100-0000 0000-0000 0000-0000 0000-0000
// 减一 1011-1111 1111-1111 1111-1111 1111-1111
// 取反0100-0000 0000-0000 0000-0000 0000-0000 -2^30=1073741824
System.out.println((int) (j << 29));
System.out.println("------正数右移------------------------------------------------------");
int k = 6; // 正数右移
System.out.println(Integer.toBinaryString((int) k));
// 正6 补码: 0000-0000 0000-0000 0000-0000 0000-0110
System.out.println(Integer.toBinaryString((int) (k >> 2)));
// 补码:0000-0000 0000-0000 0000-0000 0000-0001
System.out.println((int) (k >> 2)); // 1
System.out.println(Integer.toBinaryString((int) (k >>> 2)));// 无符号右移
// 补码:0000-0000 0000-0000 0000-0000 0000-0001
System.out.println((int) (k >>> 2)); // 1
System.out.println(Integer.toBinaryString((int) (k >> 3)));
// 补码:0000-0000 0000-0000 0000-0000 0000-0000
System.out.println((int) (k >> 3));// 0
System.out.println(Integer.toBinaryString((int) (k >>> 5)));// 无符号右移
// 补码:0000-0000 0000-0000 0000-0000 0000-0000
System.out.println((int) (k >>> 5));// 0
System.out.println("------负数右移------有符号无符号右移------------------------------------------------");
int l = -6; // 负数右移
System.out.println(Integer.toBinaryString((int) l));
// 正6 : 0000-0000 0000-0000 0000-0000 0000-0110
// 取反: 1111-1111 1111-1111 1111-1111 1111-1001
// 加一 补码: 1111-1111 1111-1111 1111-1111 1111-1010
System.out.println(Integer.toBinaryString((int) (l >> 28)));// 右移的规则只记住一点:符号位不变,左边补上符号位1
// 补码:1111-1111 1111-1111 1111-1111 1111-1111
System.out.println((int) (l >> 28)); // -1
// 减一 1111-1111 1111-1111 1111-1111 1111-1110
// 取反:0000-0000 0000-0000 0000-0000 0000-0001
System.out.println(Integer.toBinaryString((int) (l >>> 28)));// 无符号右移,忽略了符号位扩展,0补左边
// 补码:0000-0000 0000-0000 0000-0000 0000-1111
System.out.println((int) (l >>> 28)); // 15
System.out.println("------0xff------------------------------------------------------");
System.out.println(Integer.toBinaryString(0xff)); // 0000-0000 0000-0000 0000-0000 1111- 1111
System.out.println(Integer.toBinaryString(0xffff)); // 0000-0000 0000-0000 1111-1111 1111- 1111
System.out.println(Integer.toBinaryString(0xfffff)); // 0000-0000 0000-1111 1111-1111 1111- 1111
System.out.println(Integer.toBinaryString(0xfffffff)); // 0000-1111 1111-1111 1111-1111 1111- 1111
System.out.println(Integer.toBinaryString(0xffffffff)); // 1111-1111 1111-1111 1111-1111 1111- 1111
// System.out.println( Integer.toBinaryString(0xfffffffff) ); //异常
}
}
/*
1、 左移运算符
左移的规则只记住一点:丢弃最高位,0补最低位
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了33/32=1位。
在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
2、 右移运算符
右移的规则只记住一点:符号位不变,左边补上符号位:低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1
当右移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
在数字没有溢出的前提下,右移一位相当于除2,右移n位相当于除以2的n次方。
3、无符号右移
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位
无符号右移规则和右移运算是一样的,只是填充时不管左边的数字是正是负都用0来填充,无符号右移运算只针对负数计算,因为对于正数来说这种运算没有意义(一样的)
1.有符号和无符号的概念如下:
最明显的区别就是二者表示的范围不同: 无符号数中,所有的位都用于直接表示该值的大小。有符号数中最高位用于表示正负,所以,当为正值时,该数的最大值就会变小。
无符号数: 1111 1111 值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20
有符号数: 0111 1111 值:127 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20
同样是一个字节,无符号数的最大值是255,而有符号数的最大值是127。 所以无符号数比有符号数的最大值大1倍。
我们仍一个字节的数值对比:
无符号数: 0 ----------------- 255 有符号数: -128 --------- 0 ---------- 127
所以二者能表达的不同的数值的个数都一样是256个。 只不过前者表达的是0到255这256个数,后者表达的是-128到+127这256个数
2.java没有无符号类型,都是有符号类型的数据类型
在实际开发中,可能要与c写的硬件接口,网络接口相互直接数据交互,此时由于java没有无符号的数据类型,导致java与c看似相同的数据类型,
其实存储空间确是不同的,这个问题解决方法是java用更高的存储数据类型,如果c用int,你的java就要考虑用Long或者BigInteger了
*/