Java如何精确显示double而无法用二进制科学记数法精确表示?

kyo*_*iro 5 java double

根据我的理解,当为变量分配任何双精度值时,它将经历以下步骤:

  1. 转换为二进制。
  2. 对科学记数法的格式进行一些转换。
  3. 转换为 IEEE754。

步骤 1 和步骤 3 都可能会引入一些不准确的情况。所以内存中存储的值已经不准确了。

但令人惊讶的是,如果我不对这个双精度值进行任何计算,只是将其打印出来,例如: println(0.2d)

甚至

打印(1245.1325415d)

只要双精度数不太长,结果总是准确的。

将IEEE754格式转换回Base10格式时有什么技巧吗?

Pat*_*han 5

对于每个 double D,都有一个可以转换为 D 的小数分数范围。以 D 作为参数的 Double.toString 会生成该范围内有效数字最少的成员。通常,“不太长”的小数部分是其范围内有效数字最少的成员,因此它是转换为字符串时得到的小数部分。

例如:

import java.math.BigDecimal;

public class Test {
  public static void main(String[] args) {
    double d1 = 0.4;
    double d2 = 0.400000000000000000001;
    System.out.println(d1);
    System.out.println(d2);
    System.out.println(new BigDecimal(d1));
  }
}
Run Code Online (Sandbox Code Playgroud)

显示:

0.4
0.4
0.40000000000000002220446049250313080847263336181640625
Run Code Online (Sandbox Code Playgroud)

“0.4”和“0.400000000000000000001”都在其成员转换为精确值为 0.40000000000000002220446049250313080847263336181640625 的双精度值的范围内。0.4 是该范围中最短的成员,因此它是 toString 转换的结果。它也是一个“不太长”的小数。