Java 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)));
}
}
输出如下:
>java Change
Double difference
0.899999999999999911182158029987476766109466552734375
Float difference
0.900000095367431640625
Valueof Difference
0.9
我的问题是: valueOf() 做什么来获得精度? 有没有其他方法可以获得正确的结果,而无需手动四舍五入到 2 位数字?
谢谢,
I wanted to see if anyone can explain why the following code works with valueOf but not others.
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)));
}
}
The output looks like:
>java Change
Double difference
0.899999999999999911182158029987476766109466552734375
Float difference
0.900000095367431640625
Valueof Difference
0.9
My question is: What does valueOf() do to get the precision?
Is there any other way of getting the correct result without rounding off to the 2 digits manually?
thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
查看 BigDecimal 的源代码,它确实如此:
从其 JavaDoc 来看:
由于浮点表示形式,双精度值并不完全是您设置的值。但是,在字符串表示期间,它会四舍五入显示的内容。 (所有规则都在其上 JavaDoc)。
此外,由于这种舍入,如果您执行以下操作:
BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));
您将得到错误的值。 (d == 4.0)
因此,用字符串初始化它们总是更好。
Looking at the source code for BigDecimal, it does:
From its JavaDoc:
Because of floating-point representation, a double value is not exactly what you set it as. However, during String representation, it rounds off what it displays. (All of the rules are on it's JavaDoc).
Furthermore, because of this rounding, if you did:
BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));
you would get the wrong value. (d == 4.0)
So, it's pretty much always better to initialize these with strings.
BigDecimal.valueOf(double)
首先执行从 double 到 String 的转换,然后从 String 到 BigDecimal。在第一种情况下,您从 double 或 float 开始,转换为 BigDecimal,计算差异。在第二种情况下,您从 double 或 float 开始,转换为 String,然后转换为 BigDecimal,然后计算差异。
BigDecimal.valueOf(double)
first does a conversion from double to String, then String to BigDecimal.In the first case, you're starting with a double or float, converting to BigDecimal, calculating the difference. In the second case, you're starting with double or float, converting to a String, then converting to BigDecimal, then calculating the difference.
来自 Javadocs :
公共静态BigDecimal valueOf(double val)
我想这回答了你的两个问题。
干杯,
From the Javadocs:
public static BigDecimal valueOf(double val)
I think this answers both of your questions.
Cheers,
valueOf 起作用是因为它调用 Double.toString。来自 Javadoc:
当您将 double 传递到 BigDecimal 构造函数时,构造函数会获取浮点值并准确地再现它。 toString 代码查找浮点值的近似值。
如果您没有注意到,使用 System.out.println() 显示浮点数不会显示与首先将浮点数包装在 BigDecimal 中相同的结果(使用采用 double 的 BigDecimal 构造函数) )。
The valueOf works because it calls Double.toString. from the Javadoc:
When you pass a double into the BigDecimal constructor, the constructor takes the floating-point value and reproduces it exactly. The toString code finds an approximation for the floating point value.
In case you didn't notice, using System.out.println() to show a floating point number doesn't show the same results as if you wrap the floating point number in a BigDecimal first (using the BigDecimal constructor that takes a double).