Java BigDecimal的区别

tru*_*ekr 2 java double bigdecimal

我想知道是否有人可以解释为什么以下代码适用于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)));

   }
 }
Run Code Online (Sandbox Code Playgroud)

输出如下:

>java Change
 Double difference
  0.899999999999999911182158029987476766109466552734375
 Float difference
  0.900000095367431640625
 Valueof Difference
 0.9
Run Code Online (Sandbox Code Playgroud)

我的问题是:valueOf()做了什么来获得精度?有没有其他方法可以获得正确的结果而无需手动四舍五入到2位数?

谢谢,

Rev*_*nzo 8

查看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));
}
Run Code Online (Sandbox Code Playgroud)

从它的JavaDoc:

使用Double.toString(double)方法提供的double的规范字符串表示将double转换为BigDecimal.

注意:这通常是将double(或float)转换为BigDecimal的首选方法,因为返回的值等于从使用Double.toString(double)的结果构造BigDecimal所产生的值.

由于浮点表示,double值与您设置的不完全相同.但是,在String表示期间,它会将其显示的内容四舍五入.(所有规则都在它的JavaDoc上).

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

BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));

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

因此,使用字符串初始化它们总是更好.

  • 你是绝对正确的。valueOf(4.00000000000000000001)不起作用。今天学到一些新东西:)谢谢。 (2认同)