java Float.MAX_VALUE 转 Double

标签 java floating-point double

就是这段代码:

public class Main {
    public static void main(String[] args) {
      float a = Float.MAX_VALUE;
      double b = (double) a;
      b++;
      System.out.println(b == a);
}

并且它打印true。 谁能解释一下为什么吗?

最佳答案

double的精度无法表示Float.MAX_VALUEFloat.MAX_VALUE+1之间的差异,因此结果是四舍五入的被返回。舍入结果为 Float.MAX_VALUE

Float.MAX_VALUE 为 2128−2104。 (请注意,这是 2127+2126+2125+…+2104。也就是说,它是从 2127 到 2104 的所有 2 的幂之和。在二进制中,它有 24 个 1 位,即有效数的位数1float。数学上,它等于 2128−2104。)

当你加一时,数学结果当然是 2128−2104+1。这在 double 中无法表示,因为 double 的有效数是 53 位,但从 2127 到 1 是 129 位。您无法将 2127 和 1 的位同时放入 double 的有效数内。当结果不可表示时,返回最接近的可表示数字。

数学结果正下方可表示的数字是 2128−2104,数学结果正上方可表示的数字是 2128>−2104+275。 (请注意,从 2127 到 275 是 52 位,因此 275 是 53 位中的最小 2 的幂有效位数,其中最大位被缩放为 2127。因此,我们通过添加最小的位来计算高于 2128−2104 的下一个数字等于有效数字的数量。)因此我们有两个候选者:

  • 2128−2104,与 2128−2104+1 相差 1。
  • 2128−2104+275,即 2104+275 −1 距离 2128−2104+1。

前者更接近,所以选择它作为计算结果。因此,在 double 中,2128−2104 加 1 会产生 2128−2104 .

脚注

1 二进制 float 的表示由三部分组成:符号s,即+1或-1,有效数f 是具有固定位数的定点数和指数 e,这样表示的数字为 sf> • 2e。有效数可以被认为是具有一定位数的整数,但通常通过调整指数来缩放它,以便正常 float 的有效数位于 [1, 2) 中。例如,132 可以被视为有效数 1000012 乘以 22 或 1.000012 乘以 27>.

关于java Float.MAX_VALUE 转 Double,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50839713/

相关文章:

java - 使用可比接口(interface)的警告

c - 为什么带有 DBL_MIN 的 strtod() 给出 ERANGE?

c - 不同基数大整数位数的上限

java - Assertequals (double, double, delta) 问题

c - 双字段的 calloc() 是否总是计算为 0.0?

java - 如何从 double 数组中创建 double 列表

java - 如何解决 NoClassDefFoundError Java 代理

java - SocketTimeoutException cxf httpconduit PUT

java - 我不应该将哪些 java android 文件上传到我的 SVN 服务器?

java - Math.isFinite() 方法的实现