byte数据类型在显式类型转换时超出其取值范围的转换过程

Made by Mike_Zhang


Java主题:


byte数据类型简介

byte是四个整数类型(byte、short、int、long)中取值范围最小的整型数据类型,具体如下:

数据类型名称 内存大小 取值范围
byte 8b(1B) -128~127(2^8)
short 16b(2B) -32768~32767(2^16)
int 32b(4B) -2147483648~2147482647(2^32)
long 64b(8B) -9223372036854775808~9223372036854775807(2^64)

数据类型转换

数据类型转换分为隐式转换显式转换(也称强制类型转换)

隐式转换指的是低精度数据类型向高精度数据类型转换,数据不会溢出,并且一定成功,如下:

1
2
3
4
5
6
7
public class Frist {
public static void main(String[] args) {
int a = 100; //初始int变量a,初值为100
float b = a; //a赋值给float型变量b
System.out.println(b); //输出
}
}

输出结果为:
1
100.0

显式转换(也称强制类型转换) 指的是高精度数据类型转换向低精度数据类型,转换时可能会造成数据精度损失,如下:

1
2
3
4
5
6
7
8
public class Frist {
public static void main(String[] args) {
int a = (int)100.99; //从浮点型到整型
short b = (short)12.3f; //从浮点型到整型
System.out.println(a); //输出
System.out.println(b); //输出
}
}

输出结果为:
1
2
100
12


byte类型显式转换时超出其取值范围

若我们运行以下代码:

1
2
3
4
5
6
public class Frist {
public static void main(String[] args) {
byte a = (byte)129;
System.out.println(a);
}
}

输出结果为:
1
-127

因为byte数据类型的取值范围是-128~127,以上例子中被转换的数值为129,已经超出了byte数据类型的取值范围,所以不能正常显示为129,而现实了看似奇怪的-127.
其实,-127并不是凭空出现的,而是因为byte数据类型对于超出其取值范围的强制类型转换有特殊的处理过程。

步骤为:

1.保留被转换数值补码的低字节部分;
2.将保留下来的部分转换成原码。

(这里不会对原码,反码,补码等概念进行讲解,若不了解的,请自行搜索)

接下来以129为例:

第一步 保留被转换数值补码的低字节部分
129的原码为 0…0 1000 0001(原)
保留其低字节部分后为:
1000 0001(原)

第二步 将保留下来的部分转换成原码
因为程序是以补码处理数值的,所以上一步中的1000 0001(原)将会被看成补码1000 0001(补)
接下来将补码还原成原码:
1000 0001(补) >>> 1000 0000(反) >>> 1111 1111(原)
1111 1111(原) 即为-127(1111 1111(原) 的最高位是符号位,1表示负数,余下的 111 1111 即为十进制的127,所以1111 1111(原) 为-127)

所以以上步骤解释了byte a = (byte)129;的输出结果为-127。


写在最后

在研究过程中发现,其实原码、反码、补码中可以深挖的东西还有好多,都十分有趣,之后也会记录。
最后,希望大家一起交流,分享,指出问题,谢谢!


原创文章,转载请标明出处
Made by Mike_Zhang




感谢你的支持

byte数据类型在显式类型转换时超出其取值范围的转换过程
https://ultrafish.io/post/Java-data-type-conversion/
Author
Mike_Zhang
Posted on
August 15, 2020
Licensed under