其他分享
首页 > 其他分享> > 类型转换与基本类型包装类

类型转换与基本类型包装类

作者:互联网

类型转换与基本类型包装类

基本数据类型转换

在实际应用中,经常需要在不同类型的值之间进行操作,这时就需要进行数据类型的转换。 数据类型转换有两种:

包装类

自动装箱与拆箱

自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。
在JDK1.5之前,基本类型转换为对象需要程序显示用包装类进行处理,有了装箱和拆箱后就自动了,程序就不需要显示处理了。例如:Integer num = 1;

【进阶】long如何自动转化为float?

long占八个字节,float只占四位,如何能自动转化呢?

对于byte,short,int,long四个整数类型而言,它们在内存中无一例外都是直接换算成二进制存储的,所以我们可以直接计算出它们的最大值。
二进制的第一位是符号位不计算入数值,所以Byte的最大值是01111111,即127

而浮点型在内存中的存储结构是不同的:
float在内存中占4个字节,共32位,但是浮点数在内存中是这样的:
  V=(-1)^s ∗ M ∗ 2^E
浮点数的32位不是简单的直接表示大小,而是按照一定的标准分配的。

所以这就是为什么float虽然只用到了4个字节,但是浮点数表述范围却比长整型long的表述范围要大的原因了。由此就可以就解释的通为什么小范围的long能自动转型成为大范围float了。

简单计算一下float的范围

2^-127 ~ 2^128-1,很明显比long的 [2^63 - 1 , -2^63]范围大

为什么long类型转float可能存在精度丢失的问题

V=(-1)^s ∗ M ∗ 2^E
M区域(小数域),M的取值范围为[1,2)或[0,1)。
所以尽管float的表数范围很大,但是不是区间内所有的值都一定能精确表示的。所以在long转float时可能存在精度丢失。
【范例】

    int a = 123456789;
    float f = a;
    double d = a;
    System.out.println("原始int值a: " + a);
    System.out.println("a转换为float精度损失:" + f);
    System.out.println("a转换为double精度未损失:" + d);
    long l = 1234567899999999l;
    f = l;
    System.out.println("long类型" + 1 + "转换为float,精度损失: " + f);

输出为:

原始int值a: 123456789
a转换为float精度损失:1.23456792E8
a转换为double精度未损失:1.23456789E8
long类型1转换为float,精度损失: 1.23456795E15

【备注】在进行货币等精确计算时应使用BigDecimal。
程序中如果对精度要求不是很高的情况,可以使用float。但精度要求高的情况,要尽量使用double。如果要求更高的精度,则应使用BigDecimal

进一步理解精度丢失

在百度上搜到一个很形象的答复,就是int是准确值,而float是精确值,准确转精确当然会精度丢失。
Int是4字节32位来表示的,而float虽然也是4字节32位,但是float的存储结构是很不一样的

156795497950633
以这一例子来说明,由图可知,float的存储结构是1个符号位,8个指数位,23个尾数。

符号位,表述浮点数的正或者负,0代表正,1代表负。

指数位,实际也是有正负的,但是没有单独的符号位,在计算机的世界里,进位都是二进制的,指数表示的也是2的N次幂,8位指数表达的范围是0到255,而对应的实际的指数是-127到128。也就是说实际的指数等于指数位表示的数值减127。这里特殊说明,-127和+128这两个指数数值在IEEE当中是保留的用作多种用途的,这里就不多做介绍了,有兴趣的可以查阅其他资料。【其实这个就是IEEE的定义,因为公式中是2的N次幂-127,这个跟JAVA中byte值范围不一样】

尾数位,只代表了二进制的小数点后的部分,小数点前的那位被省略了,当指数位全部为0时省略的是0否则省略的是1。

由此我们可以明白,实际上尾数确定了浮点数的精度,而数的大小主要是靠指数位,尾数只有23位,加上省略的那一位便是24位,所以如果int类型的值在2^24以内,float是可以精确表示的,但是当超过这个数的时候就不一定能精确表示了。这里最重要的一点便是要理解确定精度的有效位数,不管是什么基本类型转换实际上都要明白这一点。就如int与float,都是32位,但是内存结构既存储结构是不一样的,float只能有24位来确定精度,而int是32位。其他类型也如此进行理解即可。

在讲这公式之前讲一下我在理解过程中遇到的难题,就是尾数的23位值为什么是介于1.0和2.0之间,当时看到一直想不明白,后来才了解到这23位是用来表示小数位的,而省略的那一位是1,因为0是没有意义的(因为如果是0,一个小数的不管乘以多少都是小数)。再次强调这里的尾数23位是表示小数位的。

156795497950633
就以图的例子来讲。

符号位我想不用我讲了
指数位就跟我们算十进制一样的方法,可以算出指数位是124(算法我就不在这里说了,网上自己查一下),套入以上的表达式的最后一个,既是2^(124-127) = 2^(-3)
然后尾数部分,看它的公式就可以看出来,b23-i就是尾数部分的哪一位数,i取1的时候就b22,既最左边的部分,然后再乘以2的负i次方。从上面这一公式也可以看出,尾数部分是介于1.0和2.0之间。【尾数部分:1+2的-2次方,值为1.25;再乘以指数部分的2的-3次方,相当于除以8,值为0.15625】

标签:类型转换,包装,float,int,自动,类型,Integer,装箱
来源: https://www.cnblogs.com/faetbwac/p/16353467.html