为什么你可以在没有类型转换的情况下将长存储到浮点数中[重复]

问题描述 投票:3回答:2

这个问题在这里已有答案:

好的,我知道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;

请注意,问题具体是关于longfloat没有明确的演员,而不是floatlong,而不是关于显式演员。

java casting long-integer
2个回答
6
投票

long转换为float是一个widening primitive conversion。 Java允许它没有错误,因为......它是这样定义的。从链接:

对原始类型的19个特定转换称为扩展原始转换:

  • byteshortintlongfloatdouble
  • shortintlongfloatdouble
  • charintlongfloatdouble
  • intlongfloatdouble
  • longfloatdouble

...

intfloat,或从longfloat,或从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不同,它可以精确地表示这些整数中的每一个。


-3
投票

有类似隐式类型转换的东西。如果您不丢失信息,Javajava会自动投射它。从float到long你可能会丢失浮点后的所有内容,所以不会有隐式转换,因为通常你不想丢失这些信息。

© www.soinside.com 2019 - 2024. All rights reserved.