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; // 编译通过

结论:

  1. 赋值运算需要保证精度,只可小转大,不可大转小
  2. 当容量小的数据类型的变量与容量大的数据类型的变量进行运算时,结果自动提升为容量大的数据类型。
  3. 容量大小指的时表示数的范围大和小,如float的容量大于long。
  4. 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;
  1. 求以上程序的结果
    1. 原始数据: 00000000 00000000 00000000 10000010

    2. 强转后(补码): 10000010

    3. 补码转反码再转原码: 10000001(补码减1)

      ​ 11111110(反码除符号位全部取反)

    4. 补码的补码: 11111101(除符号位全部取反)

      ​ 11111110(加1) = -126(字面值)

    5. 以上两个方法得到的结果一致,故原码=补码的补码

  • 在八位二进制下,-128不能用原码或反码表示,反码只能表示0到127,-0到-127;
  • 用补码表示为:10000000
  • 在八位整数里原码的取值范围为-127到+127,反码也是
  • 在八位二进制中就把-0当作最小数-128用,也就是10000000
    • -0的原码:10000000
    • -0的反码:11111111
    • -128的补码:10000000
posted @ 2021-04-15 00:10  TSCCG  阅读(118)  评论(0编辑  收藏  举报