本文主要是精髓在于Java基本数据类型强转带来的精度丢失问题,嗯…看后如有更好的想法欢迎留言哦!
一、Java中的基本数据类型
在内存中,1G=1024M; 1M=1024k ; 1k=1024bit(位) ; 其中又有1字节=8位
1、整型
(1)、byte
//byte :字节 ,1字节 =8位 有效范围: -2^7~2^7-1
byte b1 = 123;
byte b2 = 129; //报错,超出了2^7-1
(2)、short
//short: 大小: 2字节=16位 有效范围: -2^15~2^15-1
short s = 123;
(3)、int
//int(Java中默认的整型),大小: 4字节=32位 有效范围: -2^31~2^31-1
int i = 123;
(4)、long
//long: 大小: 8字节=84位 有效范围: -2^63~2^63-1
//注意:long类型的数据需要在其后面加上“L” ,
//因为默认为int类型,不加就存在一个隐式转换关系在里面,明白就好^_^
long l = 1234L;
2、浮点型
(1)、float
//float: 单精度 大小: 4字节=32位 有效范围: -2^31~2^31-1
float f = 123.4F;
/*
因为Java中默认的浮点型为double,不加F,编译器会认为123.4是一个double类
型的数,当将一个double类型的数赋值给float类型时就需要进行强转了,
所以在后面加F表明123.4为float类型数据。
*/
(2)、double
//double:(Java中默认的浮点型) 双精度 大小: 8字节=64位 有效范围: -2^63~2^63-1
double d = 123.456D;//后面的D可加可不加,因为默认为double类型。
3、字符型
1、char
①接收字符,表示的是单个字符,只能接收一个字符
char c1='中';
②接收整型,最大2字节16位 表示的是:JVM会去查找ascii码表数值对应的字符
char c2=49;
char c3=65;
System.out.println("c2:"+c2+" c3:"+c3);//c2:1 c3:A
③接收Uncode字符 以\ u开头的字符:JVM会去查找Uncode码表数值对应的字符
char c5='\u03A6';
System.out.println(c5);//Φ
④接收16进制就是接收整型:将16进制转为10进制再对应的ascii码值
char c6=0x23;
System.out.println(c6);//#
转义字符:使用”\”把其转化成字符的本身输出,那么使用”\”的字符称作为转义字符。
System.out.println("你好\"中国\"");//你好"中国"
4、布尔型
1、boolean
在官方文档中有着这么一句话:This data type represents one bit of information, but its “size” isn’t something that’s precisely defined.
也就是说在Java中定义的八种基本数据类型中,七种类型都有明确的内存占用字节数,就boolean类型没有给出具体的占用字节数。
Java虚拟机规范中定义:在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后统一使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个boolean元素占8位。
boolean temp=false;
boolean temp1=true;
二、Java中的基本数据类型之间的转换
在进行转换之前首先要了解基本数据类型的精度高低(大小)顺序,即
byte < short < int < long < float < double
这里面要注意的一点就是有些人可能会搞不懂为什么64位的long精度会比32位的float低(小),因为浮点型的数据精度都比整型的高(大),记住就行!
另外,不同基本数据类型进行计算时,会先转为其中最大精度的数值类型再做计算。
例如,在计算时byte、short、char之间不会相互转换,他们三者在计算时首先会转换为int类型。
1、隐式转换
//当从低精度数据类型转换为高精度数据类型时会自动转换,也称为隐式转换。例如:
byte b = 123;
int i = b;
2、显式转换
//当从高精度数据类型转换为低精度数据类型时,就要进行强制转换,即强转。例如:
int i = 129;
byte b = (byte)i; //此时会发生精度丢失,不信在控制台输出一下b
三、强转出现精度丢失的问题
正如我们上面提到精度丢失的原因,以及在进行强转时出现精度丢失现象,以下针对此问题进行分析。
1、引言
进行分析前要明确一个知识,那就是计算机在存储数值类型数据时在内存中数据是以什么形式存在的!
答案就是:数据存储是以二进制补码形式存在于内存中,读取显示的时候先将补码转为原码输出显示
①针对于二进制: 第一位为符号位:1表示负数 0表示正数
② 正数的原码、反码、补码都一样
③ 负数: 反码:原码除了符号位不变之外其余取反 , 补码=反码+1
④补码转原码:补码-1,然后除了符号位以外其余取反
2、上菜
public static void main(String[] args) {
//将高精度的数转化为低精度的数并且超出低精度的数的数值范围时就会造成精度丢失
int i=129;
byte b = (byte)i;
System.out.println(b); //-127
}
3、思路
在上面代码中,我们知道:
int类型数据为32位,byte类型数据为8位,当将int类型数据转为byte类型数据时,实质上就是截取int后8位存到byte中。
原理:
129的原反补码都一致为:0000 0000 0000 0000 0000 0000 1000 0001
进行转换时截取后8位为:1000 0001
此时得到的数据为补码,其原码为:
补码(1000 0001)–> 反码(1000 0000)–> 原码(1111 1111)
即(1111 1111)就是 (byte)i 的结果:
即b=-(64+32+16+8+4+2+1)=-127