Javase学习-02基本数据类型之间的运算规则
Javase学习-基本数据类型之间的运算规则
1.基本数据类型
四类八种:
-
整数型:
- byte(1byte = 8bit)
- short(2byte)
- int(4)
- long(8)
-
浮点型:
- float(4)
- double(8)
-
字符型:
- char(2)
-
布尔型:
- boolean(1bit = 1/8byte)
以下讨论的只涉及7种基本数据类型的运算,不包含boolean类型
2.自动类型提升
//1.+ 2.*****************************
int b1 = 10;
byte n2 = b1 + a2; //错误: 不兼容的类型: 从int转换到byte可能会有损失
int n3 = b1 + a2; //编译通过
//3.********************************
float d1 = 1.0F;
long d2 = 100;
long m1 = d1 + d2; // 错误: 不兼容的类型: 从float转换到long可能会有损失
//4.******************************
byte a1 = 1;
byte a2 = 12;
byte n1 = a1 + a2;// 错误: 不兼容的类型: 从int转换到byte可能会有损失
char c1 = 'a';
short c2 = 10;
short n4 = c1 + c2; // 错误: 不兼容的类型: 从int转换到short可能会有损失
char n5 = c1 + c2; // 错误: 不兼容的类型: 从int转换到char可能会有损失
int n6 = c1 + c2; // 编译通过
结论:
- 赋值运算需要保证精度,只可小转大,不可大转小
- 当容量小的数据类型的变量与容量大的数据类型的变量进行运算时,结果自动提升为容量大的数据类型。
- 容量大小指的时表示数的范围大和小,如float的容量大于long。
- byte、char、short --> int --> long -->float --> double
- 当byte、char、short三种类型的变量进行运算时,结果均为int型
3.强制类型转换
long x = 10L;
- 10L是long类型字面值,x是long类型变量,不存在类型转换,直接赋值。
double x = 13.9; // double类型,8个字节
int y = x // int类型,4个字节
-
编译报错
-
大容量数据类型不能直接赋值给小容量数据类型
-
大容量转换成小容量,需要进行强制类型转换,要加“强制类型转换符”
-
进行强制类型转换后,编译通过,但在运行阶段可能会损失精度
x = (int)y; // y = 13,精度损失
3.1强转原理
int x = 10;
byte y = (byte)x;
- 原始数据x: 00000000 00000000 00000000 00001010
- 强转后数据y: 00001010
- 将左边的二进制砍掉,得到y
- 00001010目前储存在计算机内部,计算机存储数据都是采用补码的形式存储,所以00001010现在是一个补码形式
- 将以上的补码转换成原码就是最终结果
byte a = 50; // 编译通过
byte b = 127; // 编译通过
- 按当前所学知识,以上代码是无法编译通过的,理由:
- 50是int类型的字面值,a是byte类型的变量,明显是大容量转换成小容量。
- 大容量转换成小容量需要添加强制类型转换符,而以上程序并没有添加强制类型转换符,故应编译错误。
- 但是,在实际编译过程中,以上程序是可以编译通过的,这说明:
- 在java语言中,当一个整数型字面值没有超出byte类型取值范围时,该字面值可以直接赋给byte类型的变量。
byte c = 128; // 编译报错
- 128这个int类型的字面值已经超出了byte类型的取值范围,故编译报错。
4.原码、反码、补码
表示法 | 描述 |
---|---|
原码 | 二进制定点表示法,最高位为符号位,“0”表示正数,“1”表示负数,其余位表示数值大小 |
反码 | 正数的反码与原码相同;负数的反码为原码符号位不变,其余位数字取反 |
补码 | 正数的补码与原码相同;负数的补码为其反码的末位加1 |
byte c = (byte)130;
- 求以上程序的结果
-
原始数据: 00000000 00000000 00000000 10000010
-
强转后(补码): 10000010
-
补码转反码再转原码: 10000001(补码减1)
11111110(反码除符号位全部取反)
-
补码的补码: 11111101(除符号位全部取反)
11111110(加1) = -126(字面值)
-
以上两个方法得到的结果一致,故原码=补码的补码
-
- 在八位二进制下,-128不能用原码或反码表示,反码只能表示0到127,-0到-127;
- 用补码表示为:10000000
- 在八位整数里原码的取值范围为-127到+127,反码也是
- 在八位二进制中就把-0当作最小数-128用,也就是10000000
- -0的原码:10000000
- -0的反码:11111111
- -128的补码:10000000