为了账号安全,请及时绑定邮箱和手机立即绑定

【Java核心技术卷】深入了解Java的类型转换(低位丢失,高位溢出等问题)

标签:
Java

关于Java的两种类型转换:

第一种是强类型转换,第二种是弱类型转换.

每种类型转换都存在着一定的风险,只有清晰地去认识它们,才能够少犯错误

强类型转换

强类型转换出现的有效位数低位数据丢失(将出现逻辑错误)、范围的高位溢出(将出现异常).

这些错误是由程序员负责的,这就需要我们在进行强制类型转换的时候,要多加注意

下面让我们看一下低位丢失和高位溢出的情况


public class demo {

public static void main(String[] args) {

int x;

float y=11111111111.0f;

x = (int)11.1 +(int)22.2; //低位丢失

System.out.println(" "+x);

x = (int)y;

System.out.println(" "+x);

}

}

结果为:

在这里插入图片描述

对于低位丢失,应该很好理解,不少朋友也知道高位溢出是怎么回事,就是容量不够了呗,那么解释为什么结果是2147473647却说不太清楚

那么让我们详细看看这是什么情况

我们知道int在任何操作系统上的Java都是4个字节,也就是32位

二进制范围: -2^31 ~ 2^31 – 1

十进制范围: -2147483648 ~ 2147483647

最大十进制有效位数:10(整数部分最多不超过10位,多于10位的数字强制转化为int类型,就会出现高位溢出)


类似的:

byte(1字节) D7----------------D0

采用补码存储

二进制范围: -27 ~ +(27 – 1)

十进制范围: -128 ~ 127

最大十进制有效位数: 3

short(2字节) D15----------------D0

采用补码存储

二进制范围: -215 ~ +(215 – 1)

十进制范围: -32768 ~ 32767

最大十进制有效位数: 5

int(4字节) D31----------------D0

采用补码存储

二进制范围: -231 ~ +(231 – 1)

十进制范围: -2147483648 ~ 2147483647

最大十进制有效位数: 10

long(8字节) D63----------------D0

采用补码存储

二进制范围: -263 ~ +(263 – 1)

十进制范围: -9223772036854775808 ~ 9223772036854775807

最大十进制有效位数: 19

char(2字节) D15----------------D0

采用无符号存储:unsigned short

二进制范围: 0 ~ +(216 – 1)

十进制范围: 0 ~ 64335

最大十进制有效位数: 5

float(4字节) D15----------------D0

采用IEEE754单精度浮点数格式存储

最大二进制有效位数: D23----------------D0

最大十进制有效位数: 8

double(8字节) D63----------------D0

采用IEEE754双精度浮点数格式存储

二进制范围:

最大值为1 x (253 - 1) x 2971

最小为1 x 2-1074

十进制范围:

最大值为±1.7976931348623157 x 10308,

最小为±5 x 10-324

Number.MAX_VALUE:1.7976931348623157 x 10308 (最大表示数,理解为最大值)

Number.MIN_VALUE:5 x 10-324 (最大\小表示数,理解为最小值)

Number.NEGATIVE_INFINITY:-Infinity

Number.POSITIVE_INFINITY:Infinity

Number.NaN:NaN

最大二进制有效位数: D53----------------D0

最大十进制有效位数: 17

隐式类型转换

所谓隐式类型转换就是下图的规则:

image

高位不会出现溢出,但是可能出现有效位数低位丢失(如下图中的虚线所示),将隐式出现逻辑错误由程序员负责。

虚线的地方 要多加注意

注意整型(long) 与 float类型 一同运算的时候,要将long类型转换成float类型

上面这张图是我们引入的模型

y 表示最大十进制的位数

x 表示二进制的有效位数

比如说 float类型

image

尾数位的23位为二进制的有效位数 第32位是符号位,紧挨着的8位是 指数位

对于 int 类型第32位是符号位 其它31位是二进制的有效位数

int 2进制的有效位数 > float 2进制的有效位数

但是 int 最大十进制有效位数 小于 float 最大十进制有效位数 (也就是int 最大值 < float 最大值)

通俗点讲:

拿31位的有效位数字放到23位的有效数字中肯定不行呀

但是要注意的是int 值总的范围大小是2的32次方,而float类型因为有8位指数位,所以要大得多.

建立下面模型:

image

同理:

image

隐式类型转换可能出现低位丢失情况:

1、运算表达式

x(int) + y(float)

2、赋值表达式

y(float) = x(int)7

上面介绍过了

开始介绍下面的

3、方法调用,实参到形参的传递

方法定义:f( float y )

方法调用:o.f(x(int) )

举个例子:


//Application.java

class Person {

int ID;

int age;

Person(int ID,int age) {

this.ID = ID;

this.age = age;

}

void intfloat(int x,float y) {

System.out.println("float y =" + y + ",int x=" + x);

}

}

public class Application {

public static void main(String[] args) {

Person p = new Person(1,21);

int x = 12345678;

float y = 0;

System.out.println("------------int,float均在重叠范围---------------");

//1.赋值表达式

//输出:float y = 1.2345678E7,int x = 12345678

y = x;

System.out.println("float y =" + y + ",int x=" + x);

//2.算术运算表达式

//输出:float y = 1.2345678E7,int x = 12345678

y = 0;

y = y + x;

System.out.println("float y =" + y + ",int x=" + x);

//3.方法调用表达式实参到形参的传递

//输出:float y = 1.2345678E7,int x = 12345678

p.intfloat(x,x);

System.out.println("------------int,float不在重叠范围---------------");

x = 123456789;

y = 0;

//1.赋值表达式,出现低位丢失,丢失时的四舍五入

//输出:float y = 1.23456792E8,int x = 123456789

y = x;

System.out.println("float y =" + y + ",int x=" + x);

//2.算术运算表达式,出现低位丢失,丢失时的四舍五入

//输出:float y = 1.23456792E8,int x = 123456789

y = 0;

y = y + x;

System.out.println("float y =" + y + ",int x=" + x);

//3.方法调用表达式实参到形参的传递 ,出现低位丢失,丢失时的四舍五入

//输出:float y = 1.23456792E8,int x = 123456789

p.intfloat(x,x);

}

}

image

这是结果

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
12
获赞与收藏
52

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消