Long
的字节数多于Float
,因此我预计最高的长度可能不会完全存储在浮点数中。确实如此:
System.out.println(String.format("%d", Long.MAX_VALUE));
// 9223372036854775807
System.out.println(String.format("%.0f", (float)Long.MAX_VALUE));
// 9223372036854776000
但是如果我把这个浮点数转换回来,我怎么可能得到原来的值呢?
System.out.println(String.format("%d", (long)(float)Long.MAX_VALUE));
// 9223372036854775807
Java是如何以某种方式恢复丢失的精度的?
编辑1 :一些额外信息:
float j = Long.MAX_VALUE;
System.out.println((long)j);
// 9223372036854775807
因此,即使存储了值,效果也是一样的。 Java是否真的忽略了'演员',即使它存储了?我觉得不应该这样做;它改变了结果。
编辑2(错误,撤消)
答案 0 :(得分:4)
问题是因为(float)Long.MAX_VALUE
的结果超出了long
的范围。因此,当它被转换回来时,它会被限制在最大可表示值。
来自JLS(强调我的):
将浮点数转换为整数类型T需要两个步骤:
[...]
否则,以下两种情况之一必须为真:
[...]
值必须太大(大幅度或正无穷大的正值),第一步的结果是int或long类型的最大可表示值。
证明:
long x = Long.MAX_VALUE - 10;
System.out.println(x); // 9223372036854775797
System.out.printf("%.0f", (float)x); // 9223372036854776000
System.out.println((long)(float)x); // 9223372036854775807 (look familiar?)
(感谢@ T.J.Crowder提供的建议示例。)