上篇文章介绍了Java中存在的基本数据类型,今天我们来看下当它们在一起进行运算时,计算机是如何处理这些数据的。
1.自动类型的提升:
class Test{`
`public static void main(String[] args){`
`//double型变量转换为int型变量`
`double test = 20.6;`
`int i = (int)test ;`
`System.out.println(i); //结果为20`
`}`
`}
1.1 当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型
byte、char、short ——》long ——》float——》double
1.2 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
1.3 byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
1.4 boolean类型不能与其它数据类型运算。
1.5 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型。
2.强制类型转换:自动类型提升的逆运算
2.1 使用强转符:()
public class dateTest {
public static void main(String[] args) {
//double型变量转换为int型变量`
double num = 20.0;
int intNum = (int)num;
System.out.println(intNum);//20
}
}
2.2使用强转符可能会导致精度损失
精度损失情况一:
class Test{
public static void main(String[] args){
//double型变量转换为int型变量
double test = 20.6;
int i = (int)test ;
System.out.println(i); //结果为20
}
}
精度损失情况二:
class Test{
public static void main(String[] args){
//int型变量转换为byte型变量
int test = 128;
byte i = (byte)test ;
System.out.println(i); //结果为 -128
}
}
至于上面的结果为什么是-128,我们需要知道计算机底层是如何存储数据的
3.补充:计算机底层如何存储数据
1.进制的分类:
·十进制
由数字0—9组成,进位规则是满十进一
·二进制
由数字0—1组成,进位规则是满二进一,以数字0b或0B开头
·八进制
由数字0—7组成,进位规则是满八进一,以数字0开头
·十六进制
由数字0—9和字母a—f组成,进位规则是满十六进一,以0X或0x开头表示
2.进制的转换
二进制——>十进制
下图为 二进制——>十进制的过程
原码、反码、补码
计算器数据的存储使用二进制的补码的形式来存储,并且最高位是符号位
·正数的补码、反码、原码一样,称为三码合一。
·负数的原码:把十进制转换为二进制,然后最高位设置为1
·负数的反码:在原码的基础上,最高位不变,其余位取反(0变1,1变0)
·负数的补码:反码+1
下图为-11在计算机底层存储的形式
给一段二进制数,求它对应的十进制(如无特别说明,则默认给的是补码),下图为求十进制的过程
十进制——》二进制
二进制——》八进制
见下图,三位为一体,将求得的数进行拼接,求得方法与二进制转十进制的方法一样
如101就代表5(2^2 +2^0),其中最大的是111(7)
二进制——》十六进制
与二进制转换为八进制的过程大致一样,不同点是:八进制是三位一组,十六进制是四位一组
八进制、十六进制 ——》二进制
八进制是将一个八进制数拆分为三个二进制数,之后再按照顺序进行拼接
十六进制是将一个十六进制数拆分为四个二进制数,之后再按照顺序进行拼接
各进制之间的转换
可以先将各进制都转换成二进制,再转换为需要的进制
回到上面的问题:为什么将int类型的128强转为byte类型就变成了-128?
这是因为在 Java 中,byte 类型是一个有符号的 8 位整数类型,取值范围为 -128 到 +127。而 int 类型是一个有符号的 32 位整数类型,取值范围为 -2147483648 到 +2147483647。
所以,当我们把一个 int 型变量转换成 byte 型变量时,如果 int 型变量的值超出了 byte 型变量的取值范围,就会发生数据溢出(也称为“截断”),只取其低 8 位的值。由于 byte 型变量是有符号的,因此超出范围的值会被认为是负数。
在这个例子中,int 变量 test
的值为 128,而这个值超出了 byte 变量的取值范围。因此,在将其转换成 byte 变量 i
时,发生了数据溢出,并只取其低 8 位的值,即二进制的 10000000,这个值在补码表示法下是一个负数,其十进制值为 -128。因此,代码的输出结果是 -128。