这个问题在这里已有答案:
好的,我知道float是32位十进制。 Double是64位十进制。长是64位整数。那么为什么这个值:Float(32位)< - Long(64位)。显然不是java代码,但我在java中引用它。即使它将其压缩成32位并且失去精度,它也会自动进行转换。这意味着精确无关紧要。但是,除非您将double显式地转换为int,否则int < - double不起作用。它是一个较小的尺寸,它们既是数字又是原始的。它只是一般规则:十进制数< - 无论位大小如何都是整数。它只会绕回来。只是那个规则和Java中的Numbers之间的一切都有效吗?要显示实际代码:
long L = 10_000L;
float f = L;
请注意,问题具体是关于long
到float
没有明确的演员,而不是float
到long
,而不是关于显式演员。
将long
转换为float
是一个widening primitive conversion。 Java允许它没有错误,因为......它是这样定义的。从链接:
对原始类型的19个特定转换称为扩展原始转换:
byte
到short
,int
,long
,float
或double
short
到int
,long
,float
或double
char
到int
,long
,float
或double
int
到long
,float
或double
long
到float
或double
...
从
int
到float
,或从long
到float
,或从long到double的扩展原始转换可能导致精度损失 - 也就是说,结果可能会丢失该值的一些最低有效位。在这种情况下,使用IEEE 754舍入到最接近模式(第4.2.4节)生成的浮点值将是整数值的正确舍入版本。
(我的重点。)
为什么不需要明确的演员表而允许它?一般来说,当时只有James Gosling和其他人可以回答这类问题。对于我们其他人来说,答案是:因为这就是规范所说的。
但是,我会注意到,即使精确度丢失,总体幅度也不会,我敢下注是为什么允许它。 float
可以不精确地保持非常大的价值。例如:
class Demo {
public static void main(String[] args) {
long l = Long.MAX_VALUE;
float f = l;
System.out.println(l);
System.out.println(f);
}
}
运行它,你得到:
9223372036854775807 9.223372E18
9.223372e18是9223372000000000000.比较:
9223372036854775807 - the long value 9223372000000000000 - the float value
这是因为float
可以牺牲值的范围精度,因为它存储了它引用指数的基值。来自Wikipedia's article on the IEEE-754 binary32 format(这是Java的float
):
... IEEE 754 32位base-2浮点变量的最大值为(2 - 2-23)×2127≈3.402823×1038 ......
3.402823×1038是:
340,282,300,000,000,000,000,000,000,000,000,000,000
...但它可以存储的最高整数,你可以加1而不失精度只是224-1(16,777,215)。它可以存储16,777,216,但不能存储16,777,217。所以16,777,216 + 1仍然是16,777,216:
class Demo {
public static void main(String[] args) {
float f = 16_777_216f;
System.out.println(String.format("%8.0f", f)); // 16777216
System.out.println(String.format("%8.0f", f + 1)); // 16777216 (still)
}
}
那是因为它现在存储的基值除以2,指数为2,因此它不再存储奇数。它越高越好,只能存储4的倍数,然后是8的倍数,然后是16的倍数等。
对比qazxsw poi的最大值,即263-1,这是“唯一的”:
9,223,372,036,854,775,807
但与long
不同,它可以精确地表示这些整数中的每一个。
有类似隐式类型转换的东西。如果您不丢失信息,Javajava会自动投射它。从float到long你可能会丢失浮点后的所有内容,所以不会有隐式转换,因为通常你不想丢失这些信息。