宽化类型转换
~~~~~~
a. 转换规则:Java虚拟机直接支持以下数值的宽化类型转换(widening numeric conversion,小范围类型向大范围类型的安全转换)。也就是说,并不需要指令执行,包括:
~~~~~~
~~~~~~
i. 从int类型到long、float或者double类型,对应的指令为:i2l、i2f、i2d
~~~~~~
~~~~~~
ii. 从long类型到float、double类型,对应的指令为:l2f、l2d
~~~~~~
~~~~~~
iii. 从float类型到double类型,对应的指令为:f2d
~~~~~~
~~~~~~
简化为:int --> long --> float --> double
~~~~~~
b. 精度损失问题:
~~~~~~
~~~~~~
i. 宽化类型转换是不会因为超过目标类型最大值而丢失信息的。例如从int转换到long,或者从int转换到double,都不会丢失任何信息,转换前后的值是精确相等的
~~~~~~
~~~~~~
ii. 从int、long类型数值转换到float,或者long类型数值转换到double时,将可能发生精度丢失——可能丢失掉几个最低有效位上的值,转换后的浮点数值是根据IEEE754最接近舍入模式所得到的正确整数值
~~~~~~
~~~~~~
iii. 尽管宽化类型转换实际上是可能发生精度丢失的,但是这种转换永远不会导致Java虚拟机抛出运行时异常
~~~~~~
c. 补充说明:
~~~~~~
~~~~~~
i. 从byte、char和short类型到int类型的宽化类型转换实际上是不存在的。对于byte类型转为int,虚拟机并没有做实质性的转化处理,只是简单地通过操作数栈交换了两个数据。而将byte转为long时,使用的是i2l,可以看到在内部byte在这里已经等同于int类型处理,类似的还有short类型,这种处理方式有两个特点:
~~~~~~
~~~~~~
~~~~~~
1) 一方面可以减少实际的数据类型,如果为short和byte都准备一套指令,那么指令的数量就会大增,而虚拟机目前的设计上,只愿意使用一个字节表示指令,因此指令总数不能超过256个,为了节省指令资源,将short和byte当作int处理也在情理之中
~~~~~~
~~~~~~
~~~~~~
2) 另一方面,由于局部变量表中的槽位固定为32位,无论是byte或者short存入局部变量表,都会占用32位空间。从这个角度说,也没有必要特意区分这几种数据类型
~~~~~~
窄化类型转换
~~~~~~
a. 转换规则:Java虚拟机也直接支持以下窄化类型转换:
~~~~~~
~~~~~~
i. 从int类型至byte、short或者char类型,对应的指令有:i2b、i2c、i2s
~~~~~~
~~~~~~
ii. 从long类型到int类型,对应的指令有:l2i
~~~~~~
~~~~~~
iii. 从float类型到int或者long类型,对应的指令有:f2i、f2l
~~~~~~
~~~~~~
iv. 从double类型到int、long或者float类型,对应的指令有:d2i、d2l、d2f
~~~~~~
b. 精度损失问题:
~~~~~~
~~~~~~
i. 窄化类型转换可能会导致转换结果具备不同的正负号、不同的数量级。因此,转换过程很可能会导致数值丢失精度
~~~~~~
~~~~~~
ii. 尽管数据类型窄化转换可能会发生上限溢出、下限溢出和精度丢失等情况,但是Java虚拟机规范中明确规定数值类型的窄化转换指令永远不可能导致虚拟机抛出运行时异常
~~~~~~
c. 补充说明:
~~~~~~
~~~~~~
i. 当将一个浮点值窄化转换位整数类型T(int或long)的时候,将遵循以下转换原则:
~~~~~~
~~~~~~
~~~~~~
1) 如果浮点值是NaN,那转换结果就是int或long类型的0
~~~~~~
~~~~~~
~~~~~~
2) 如果浮点值不是无穷大的话,浮点值使用IEEE754向零舍入模式取整,获得整数值v,如果v在目标类型T(int或long)的表示范围之内,那转换结果就是v。否则,将根据v的符号,转换为T所能表示的最大或者最小正数
~~~~~~
~~~~~~
ii. 当将一个double类型窄化转换为float类型时,将遵循以下转换原则:
~~~~~~
~~~~~~
~~~~~~
1) 通过向最接近数舍入模式舍入一个可以使用float类型表示的数字,最后结果根据下面这3条规则判断:
~~~~~~
~~~~~~
~~~~~~
a) 如果转换结果的绝对值太小而无法使用float来表示,将返回float类型的正负零
~~~~~~
~~~~~~
~~~~~~
b) 如果转换结果的绝对值太大而无法使用float来表示,将返回float类型的正负无穷大
~~~~~~
~~~~~~
~~~~~~
c) 对于double类型的NaN值将按规定转换为float类型的NaN值
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。