【问题标题】:Java BigDecimal differenceJava BigDecimal 的区别
【发布时间】:2011-05-16 17:56:55
【问题描述】:

我想看看是否有人可以解释为什么下面的代码适用于 valueOf 而不是其他的。

import java.math.BigDecimal; 
public class Change {
   public static void main(String args[]) {
     double a = 4.00d;
     double b = 3.10d;
     BigDecimal a1 = new BigDecimal(a);
     BigDecimal b1 = new BigDecimal(b);
     BigDecimal diff = a1.subtract(b1);
     System.out.println("Double difference");
     System.out.println(diff);

     float c = 4.00f;
     float d = 3.10f;
     BigDecimal a2 = new BigDecimal(c);
     BigDecimal b2 = new BigDecimal(d);
     BigDecimal diff2 = a2.subtract(b2);
     System.out.println("Float difference");
     System.out.println(diff2);

     System.out.println("Valueof Difference");
     System.out.println(BigDecimal.valueOf(4.00).subtract(BigDecimal.valueOf(3.10)));

   }
 }

输出如下:

>java Change
 Double difference
  0.899999999999999911182158029987476766109466552734375
 Float difference
  0.900000095367431640625
 Valueof Difference
 0.9

我的问题是: valueOf() 做什么来获得精度? 有没有其他方法可以在不手动四舍五入到 2 位的情况下获得正确的结果?

谢谢,

【问题讨论】:

  • 如果您想玩弄精度,可以考虑将 MathContext 参数添加到 BigDecimal 构造函数。

标签: java double bigdecimal


【解决方案1】:

查看 BigDecimal 的源代码,确实如此:

public static BigDecimal valueOf(double val) {
    // Reminder: a zero double returns '0.0', so we cannot fastpath
    // to use the constant ZERO.  This might be important enough to
    // justify a factory approach, a cache, or a few private
    // constants, later.
    return new BigDecimal(Double.toString(val));
}

来自其 JavaDoc:

将 double 转换为 BigDecimal, 使用双精度字符串 代表提供的 Double.toString(double) 方法。

注意:这通常是首选的方式 将双精度(或浮点数)转换为 BigDecimal,因为返回的值为 等于从 构造一个 BigDecimal 从 使用结果 Double.toString(double).

由于浮点表示,双精度值与您设置的不完全相同。但是,在字符串表示期间,它会四舍五入它显示的内容。 (所有规则都在JavaDoc上)。

此外,由于这种四舍五入,如果您这样做了:

BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));

你会得到错误的值。 (d == 4.0)

所以,用字符串初始化它们总是更好。

【讨论】:

  • 你是绝对正确的。 valueOf(4.000000000000000000001) 不起作用。今天学到了新东西:)谢谢。
【解决方案2】:

BigDecimal.valueOf(double) 首先进行从 double 到 String 的转换,然后从 String 到 BigDecimal。

在第一种情况下,您从 double 或 float 开始,转换为 BigDecimal,计算差异。在第二种情况下,您从 double 或 float 开始,转换为 String,然后 转换为 BigDecimal,然后计算差异。

【讨论】:

    【解决方案3】:

    来自Javadocs

    public static BigDecimal valueOf(double val)

    将 double 转换为 BigDecimal, 使用双精度字符串 代表提供的 Double.toString(double) 方法。笔记: 这通常是首选的方式 将双精度(或浮点数)转换为 BigDecimal,因为返回的值为 等于从 构造一个 BigDecimal 从 使用结果 Double.toString(double).

    我认为这回答了你的两个问题。

    干杯,

    【讨论】:

      【解决方案4】:

      valueOf 有效,因为它调用 Double.toString。来自 Javadoc:

      public static BigDecimal valueOf(double val)
      
          Translates a double into a BigDecimal, using the double's
      

      规范的字符串表示 由提供 Double.toString(double) 方法。

      当您将 double 传递给 BigDecimal 构造函数时,构造函数会获取浮点值并精确地复制它。 toString 代码找到浮点值的近似值。

      如果您没有注意到,使用 System.out.println() 显示浮点数不会显示与首先将浮点数包装在 BigDecimal 中相同的结果(使用 BigDecimal 构造函数需要双倍)。

      【讨论】:

        猜你喜欢
        • 2020-06-08
        • 1970-01-01
        • 1970-01-01
        • 2014-02-26
        • 1970-01-01
        • 2015-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多