为什么不输入类型转换就可以将long存储为浮点数

gma*_*cks 3 java casting long-integer

好的,所以我知道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;
Run Code Online (Sandbox Code Playgroud)

请注意,问题是专门针对没有显式强制转换的问题longfloat而不是float针对long,而不是有关显式强制转换的问题。

T.J*_*der 6

转换longfloat正在扩展的原始转换。Java允许它没有错误,因为...是以这种方式定义的。从链接:

关于原始类型的19种特定转换称为扩展原始转换:

  • byteshortintlongfloat,或者double

  • shortintlongfloat,或者double

  • charintlongfloat,或者double

  • intlongfloatdouble

  • longfloatdouble

...

intfloat或从long到到float从long到double的原始转换范围扩大可能会导致精度降低 -也就是说,结果可能会丢失该值的某些最低有效位。在这种情况下,使用IEEE 754舍入到最近模式(第4.2.4节),结果浮点值将是整数值的正确舍入版本。

(我的重点。)

为什么允许它而不需要显式强制转换?通常,只有詹姆斯·高斯林和当时的其他人可以回答这种问题。对于我们其他人,答案是:因为这就是规范所说的。

但是,我要指出的是,即使精度损失了,整体的幅度也没有,我敢打赌这就是为什么允许这种精度的原因。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);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行它,您会得到:

9223372036854775807
9.223372E18

9.223372e18是9223372000000000000。比较:

9223372036854775807-长值
9223372000000000000-浮点值

这是因为它float会牺牲取值范围的精度,因为它存储了它提高到指数的基本值。摘自Wikipedia关于IEEE-754 binary32格式(这是Java的格式float)的文章:

... IEEE 754 32位base-2浮点变量的最大值为(2?2 ?23)×2 127?3.402823×10 38 ...

3.402823×10 38为:

340,282,300,000,000,000,000,000,000,000,000,000,000,000,000

... 但是它可以存储的最高整数可以加1而不损失精度,只是2 24 -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)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是因为它现在存储的是将基值除以2并乘以2的指数,因此它不再能够存储奇数。您获得的越高,就越糟,只能存储4、8、16的倍数,等等。

与a的最大值long2 63 -1相比,后者是“ only”:

9,223,372,036,854,775,807

但是,与不同float,它可以精确地表示每个整数。

  • @gmanrocks-是的,但是规范允许这样做,我相信是因为尽管最终的“ float”可能有不同的数字,但幅度相同。我扩大了答案。 (2认同)