补码的产生以及整型表示范围
首先在计算机中存储是以二进制来存储的,并且通过补码的形式来进行存储
为什么会产生补码呢
拿byte来说,byte可以保存的范围是-128—127
取第一位为符号位的话
-1可以表示为 1000 0001
1 可以表示为 0000 0001
-1+1的结果应该是0,但是在计算机中只有二进制,所以二进制的-1和1的原码相加
结果为1000 0010 显然不为0
于是引入了反码的概念,正数的反码和原码相同,负数的反码为原码的除符号位按位取反
1的反码为0000 0001
-1的反码为1111 1110
所以-1+1的反码为1111 1111,再转换为原码,刚好为1000 0000表示-0
于是引入反码后新的问题出现了,1000 0000和0000 0000同时出现了-0和+0
为了解决两个0的问题,引入了补码,正数补码与反码原码均相同,负数补码是在反码的基础上+1
-1的补码就变成1111 1111
1的补码为0000 0001
-1+1补码就变成 1 0000 0000 由于byte只能存8位,于是由低向高取八位得到0000 0000正好与+0重合
同时1000 0000原本被规定为-0,但由于引入补码,-0不再被需要,所以1000 0000被规定为-128
于是整个byte的取值范围为-128—127
同理可知:short 16位、2字节 范围:负2的15次方~2的15次方减1
int 32位、4字节 范围:负2的31次方~2的31次方减1
long 64位、8字节 范围:负2的63次方~2的63次方减1
---------------------------------------------------------------------------------------------------------------------------------
强制类型转换
java中类型转换有隐式类型转换和强制类型转换,隐式类型转换是系统自动执行的,一般来说范围小的往范围大的转换,是隐式类型转换,范围小的转范围大的必须使用强制类型转换,比如:
class test {
public static void main(String[] args) {
int a=5;
byte b=(byte)a;
}
byte占8位,int占32位,byte可以表示的范围为-128-127,int可以表示的范围是-2^31—2^31-1,所以在byte转换int时不需要强制类型转换,系统会自动转换,而int转byte时,由于是变量的赋值,系统在编译时并不知道a的值,不知道是否在byte可表示的范围内,所以如果不进行强制类型转换系统编译会报错。
注:1.在强制类型转换时转换前是有符号数,高位补符号位,转换前是无符号数,高位补0
2.范围小转范围大在高位按规则补,范围大转范围小在范围大的低位截取。
通过一个例子来了解强制类型转换的步骤:
System.out.println((int)(char)(byte)-1);
这行代码的运行结果为65535
-1默认是int类型二进制表示为
10000000 00000000 00000000 00000001但是负数在计算机中以补码的形式存在
-1在计算机中保存为:11111111 1111111 1111111 11111111
int转换为char时截取低八位,即11111111
补码为1111111原码为10000001(原码求补码按位取反加1,补码求原码同样可以按位取反加1)
System.out.println((byte)-1);
所以这行代码的输出结果应该为-1;
在java中char占两个字节也就是16位,所以(char)(byte)-1结果是在上一步的基础上通过补符号位来补充至16位
补码:11111111 11111111 由于char是无符号的所以转为int高16位补0得到
补码:00000000 00000000 11111111 11111111有符号数int第一位为0所以为正数,原码补码都相同,即输出十进制为65535
************************************************************************************************************
注:范围大小并不是看字节数,比如float虽然是四个字节,但是范围却比long八个字节要大,所以当long转换为float时系统自动进行隐式转换,而float转换为long则采用强制类型转换。
原因在于long的取值范围大致为2^63,但是float的32位中,1位为符号位,23位为尾数位,剩下的8位为指数位,8位指数位可表示0-255,根据IEEE 754规定,0代表0,255代表无穷大,在0-255之间每个数都减去127得到-127-126这个指数范围,显然比long的63大的多。