【问题标题】:Regarding BigDecimal关于 BigDecimal
【发布时间】:2010-03-09 02:11:07
【问题描述】:

我为此双变量执行以下 java 打印命令 双重测试=58.15; 当我做一个 System.out.println(test);和 System.out.println(new Double(test).toString());它打印为 58.15。

当我执行 System.out.println(new BigDecimal(test)) 时,我得到以下值 58.14999999999999857891452847979962825775146484375

我能够理解“测试”双变量值在内部存储为 58.1499999。但是当我执行以下两个 System.out.println 时,我得到的输出是 58.15 而不是 58.1499999。

System.out.println(test);

System.out.println(new Double(test).toString());

以上两个输出为 58.15。

上面的 System.out.println 语句是否正在对值 58.1499999 进行一些舍入并将其打印为 58.15?

【问题讨论】:

    标签: java string bigdecimal


    【解决方案1】:
    System.out.println(new BigDecimal("58.15"));
    

    要从硬编码常量构造 BigDecimal,您必须始终使用类中的常量之一(ZEROONETEN)或字符串构造函数之一。原因是您将值放入 double 中,您已经失去了永远无法恢复的精度。

    编辑:polygenelubricants 是正确的。具体来说,您使用的是Double.toString 或等效的。从那里引用:

    必须打印多少位数 m 或 a 的小数部分?那里 必须至少为一位数字 表示小数部分,并且 除此之外,同样多,但只有同样多, 唯一需要的更多数字 区分参数值 双精度类型的相邻值。那 是,假设 x 是精确的 表示的数学值 由产生的十进制表示 此方法用于有限非零 论据 d.那么 d 必须是双精度 最接近 x 的值;或者如果两个双 值同样接近 x,然后 d 必须是其中之一,也是最少的 有效位的有效位 d 必须为 0。

    【讨论】:

      【解决方案2】:

      是的,println(或更准确地说,Double.toString)回合。为了证明,System.out.println(.1D); 打印出0.1,这是不可能用二进制表示的。

      另外,当使用BigDecimal 时,不要使用double 构造函数,因为这会试图精确表示一个不精确的值。请改用String 构造函数。

      【讨论】:

      • 我假设 new BigDecimal("52.15") 或 double test=52.15; new BigDecimal(new Double(test).toString()) 是一回事。如果我错了,请纠正我。我的理解是 new Double(double variable).toString 取舍入值 58.15 而不是 58.149999999。它是否进行任何舍入?所以如果我使用任何一种方法,结果都是一样的?
      • @arav:不,它们不一样。字符串构造函数不会丢失精度,但双精度已经丢失了。也就是说,当你调用构造函数时,double 已经是 58.149999。此外,它不进行任何舍入,它使用原始位来准确地构造您给它的内容。
      • 是的,Double.toString(.1D).equals("0.1"),是的,这里确实发生了舍入。 .1D 不完全是 0.1,而是 Double.toString 舍入。这是一种你不应该依赖的“两错全对”的场景。
      • Opps,是的,我误读了该评论,并与您在回答中所说的内容混在一起,然后是 OP。在 OP 中,问题是他直接在 BigDecimal 构造函数中使用了 double,这就是问题所在。
      • Double.toString(1.0000000000000001D).equals("1.0"),由于四舍五入导致精度丢失。
      【解决方案3】:

      out.printlnDouble.toString() 使用Double.toString(double) 中指定的格式。

      BigDecimal 默认使用更高的精度,如 javadoc 中所述,当您调用 toString() 时,它会输出所有字符,直至原始双精度可用的精度级别,因为 .15 没有精确的二进制表示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        • 2011-05-09
        • 1970-01-01
        相关资源
        最近更新 更多