每当我想到我对铸造和转换的理解时,我发现了另一种奇怪的行为.
long l = 123456789L;
float f = l;
System.out.println(f); // outputs 1.23456792E8
Run Code Online (Sandbox Code Playgroud)
鉴于a的long位深度比a大float,我希望为了编译它需要一个显式的强制转换.毫不奇怪,我们发现结果已经失去了精确度.
为什么这里不需要演员?
Jon*_*eet 43
同样的问题可以问long到double-这两次转换可能会丢失信息.
扩展原始转换不会丢失有关数值总体大小的信息.实际上,从整数类型扩展到另一种整数类型的转换根本不会丢失任何信息; 数值完全保留.在strictfp表达式中从float扩展到double的转换也完全保留了数值; 但是,这种不严格的转换可能会丢失有关转换值总体幅度的信息.
将int或long值转换为float,或将long值转换为double,可能会导致精度损失 - 也就是说,结果可能会丢失该值的一些最低有效位.在这种情况下,使用IEEE 754舍入到最接近模式(第4.2.4节)生成的浮点值将是整数值的正确舍入版本.
换句话说,即使您可能丢失信息,您也知道该值仍将在目标类型的整个范围内.
当然可以已经作出的选择,要求所有隐式转换在所有不失时机信息-这样int,并long以float本来明确的,long对double本来明确.(int到double是好的;一个double具有足够的精度,以准确地表示所有int值).
在某些情况下本来是有用的 - 在某些情况下不是.语言设计是妥协; 你无法赢得所有人.我不确定我做出了什么决定......
cle*_*tus 41
在Java语言规范,第5章:推广转化解决了这一问题:
5.1.2扩大原始转换
以下19种基本类型的特定转换称为扩展基元转换:
- byte to short,int,long,float或double
- 短,int,long,float或double
- char到int,long,float或double
- int到long,float或double
- 长期浮动或加倍
- 漂浮加倍
扩展原始转换不会丢失有关数值总体大小的信息.
...
将int或long值转换为float,或将long值转换为double,可能会导致精度损失 - 也就是说,结果可能会丢失该值的一些最低有效位.在这种情况下,生成的浮点值将是整数值的正确舍入版本
换句话说,JLS区分了幅度损失和精度损失.
int到byte例如是数量级的(潜在的)损失,因为你不能存储在500 byte.
longto float可能是精度损失但不是幅度因为浮子的值范围大于longs的值范围.
所以规则是:
微妙?当然.但我希望能够解决这个问题.
Pet*_*ter 15
虽然你是正确的,因为long在内部使用了比float更多的位,但java语言在扩展路径上工作:
byte - > short - > int - > long - > float - > double
要从左向右转换(扩展转换),不需要强制转换(这就是允许浮动长度的原因).要从右向左转换(缩小转换),必须进行显式转换.
小智 5
我在哪里听到过这件事。浮点数可以像我们写的那样以指数形式存储。'23500000000' 存储为 '2.35e10' 。因此,float 有空间占据 long 的值范围。以指数形式存储也是造成精度损失的原因。
| 归档时间: |
|
| 查看次数: |
36073 次 |
| 最近记录: |