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了 */