我想看看是否有人能解释为什么下面的代码可以与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()如何获得精度?有没有其他方法可以在不手动四舍五入到两位数的情况下获得正确的结果?
谢谢,
发布于 2011-05-17 02:01:48
看看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.toString( BigDecimal )方法提供的double的规范字符串表示,将double转换为double。
注意:这通常是将双精度型(或浮点型)转换为双精度型的首选方法,因为返回的值与使用Double.toString( BigDecimal )构造BigDecimal时返回的值相同。
由于浮点表示形式,双精度值并不完全是您设置的值。但是,在字符串表示期间,它会对所显示的内容进行舍入。(所有规则都在it's JavaDoc上)。
此外,由于这种四舍五入,如果您这样做了:
BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));
你会得到错误的值。(d == 4.0)
所以,用字符串来初始化它们总是更好的。
发布于 2011-05-17 02:02:28
valueOf之所以能工作,是因为它调用了Double.toString。在Javadoc中:
公共静态BigDecimal valueOf(double val)将double转换为BigDecimal,使用double的
Double.toString(double)方法提供的规范字符串表示。
当您将一个双精度值传递给BigDecimal构造函数时,该构造函数将获取浮点值并准确地重新生成它。toString代码查找浮点值的近似值。
如果您没有注意到,使用System.out.println()显示浮点数并不会显示与先将浮点数包装在BigDecimal中(使用接受双精度值的BigDecimal构造函数)相同的结果。
发布于 2011-05-17 02:03:28
BigDecimal.valueOf(double)首先执行从double到String的转换,然后将String转换为BigDecimal。
在第一种情况下,您从double或float开始,转换为BigDecimal,计算差值。在第二种情况下,从double或float开始,转换为字符串,然后转换为BigDecimal,然后计算差值。
https://stackoverflow.com/questions/6021369
复制相似问题