计算机数字的储存分为:1、无符号数,2、有符号数
- 无符号数:只能表示正数。每一位数都代表2的幂次方。只有地址用无符号数,无符号数不进行算术操作,之进行指针的加减。地址并不会造成错误的结果,而是产生一个空操作(气泡),所以无符号数不考虑溢出。
- 有符号数:可以表示负数。有符号数有三种表示法:1、原码,2、补码(计算机系统中,数值一律用补码来表示和存储),3、反码
(此处我们以8位有符号数举例)
- 原码:最高位符号位代表简单的正负符号,其他位为1代表 2^i
- 举例:0000_0001代表1,1000_0001 代表-1
- 求相反数:改变符号位
- 缺点:符号位需要额外的步骤来运算,因为结果不能提前知道。夭折得早。
- 补码:规定 x+ ~x=1111_1111= -1。最高位符号位为1代表 -2^7,其他位为1代表 2^i,且有1111_1111= -1
- 举例:
- 0000_0000=0
- 0000_0001=2^0=1
- 0000_0010=2^1=2
- 0000_0011=2^1+2^0=2+1=3
- ……
- 0111_1111=2^6+2^5+2^4+2^3+2^2+2^1+2^0=128-1=127(最大)
- 1000_0000= -2^7= -128(最小)
- 1000_0001= -2^7+2^0= -128+1= -127
- 1000_0010= -2^7+2^1= -128+2= -126
- ……
- 1111_1111= -2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0= -128+64+32+16+8+4+2+1=-1
- 求相反数:因为 x+ ~x= -1,所以 -x= ~x+1
- 缺点:无,大家都在用
- 举例:
- 反码:规定 x+~x=0。所有的正数取反就为相应的负数,正数的最高位必须预留为0,来保证取反之后负数为1而不会变成另一个正数。考虑所有正数: 0——0111_1111,就有所有负数:1111_1111——1000_0000
- 举例:
- 0000_0000=0,1111_1111= -0(0+(-0)=0)
- 0000_0001=1,1111_1110= -1
- 0000_0010=2,1111_1101= -2
- 求相反数:反码每一位的意义没有补码直接,所以是按补码求相反数运算再多一个减一操作来用反码表示
- 缺点:运算步骤比补码多。仅在早期的科学计算有优势。
- 举例:
小测试:java是补码还是反码?
补码。因为:
证据1:
1 System.out.println(~0); 2 System.out.println(~1); 3 System.out.println(~2); 4 //-1 5 //-2 6 //-3 7 //如果是反码应该输出:0,-1,-2
证据2:
1 System.out.println(Integer.MAX_VALUE); 2 System.out.println(Integer.MIN_VALUE); 3 //2147483647 4 //-2147483648 5 //如果是补码就应该是:2147483647,-2147483647,因为补码正负数个数相等,有正零、负零
证据3:
1 System.out.println(Integer.toBinaryString(Integer.MAX_VALUE)); 2 System.out.println(Integer.toBinaryString(-Integer.MAX_VALUE)); 3 //01111111111111111111111111111111 4 //10000000000000000000000000000001取反加一