java - `(long)(float)Long.MAX_VALUE` 具有准确的值,这怎么可能?

标签 java casting floating-point precision

LongFloat 具有更多字节,因此我预计最高的 long 可能不会完全存储在 float 中。事实确实如此:

System.out.println(String.format("%d", Long.MAX_VALUE));
// 9223372036854775807
System.out.println(String.format("%.0f", (float)Long.MAX_VALUE));
// 9223372036854776000

但是如果我将这个 float 转换回长整型,我怎么可能得到原始值?

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(错误,已撤消)

最佳答案

问题是因为 (float)Long.MAX_VALUE 的结果超出了 long 的范围。因此,当它转换回来时,它会被限制为最大可表示值。

来自JLS (强调我的):

A narrowing conversion of a floating-point number to an integral type T takes two steps:

[...]

Otherwise, one of the following two cases must be true:

[...]

The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or 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 提供的建议示例。)

关于java - `(long)(float)Long.MAX_VALUE` 具有准确的值,这怎么可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43279353/

相关文章:

c++ - C++将对象强制转换为其原始类型

c# - 浮点变量的范围会影响它们的值吗?

javascript - 网页 View 不加载网页图像

java - Cassandra 副本存储不平衡

java - 使用 Hibernate 的后备数据库

javascript - 如何在 JavaScript 中将字符串转换为数字并确保浮点类型?

c++ - Double 的乘法不如 float 的乘法精确

带有集合或列表的 Java 8 CompletableFuture.allOf(...)

c++ - 动态转换为 vector 迭代器

javascript - Mozilla ctypes,从 c 数组提供 Arraybuffer