这个构造函数的结果可能有些不可预测。一 可能会假设在Java中编写新的BigDecimal(0.1)会创建一个 BigDecimal正好等于0.1(未缩放的值为1,带有 比例为1),但它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能完全表示为double(或者为此) 重要的是,作为任何有限长度的二进制分数)。因此,价值 传入构造函数的不完全等于 0.1,尽管有外表。
另一方面,String构造函数是完全可预测的: 编写新的BigDecimal(" 0.1")会创建一个完全正确的BigDecimal 等于0.1,正如人们所期望的那样。因此,一般来说 建议首先使用String构造函数 之一。
当必须将double用作BigDecimal的源时,请注意 这个构造函数提供了精确的转换;它没有给出 使用。将double转换为String的结果相同 Double.toString(double)方法然后使用BigDecimal(String) 构造函数。要获得该结果,请使用静态valueOf(double) 方法
那么为什么他们只是弃用它并将功能更改为valueOf(double)?什么是不可预测的价值创造了什么?
答案 0 :(得分:5)
这是完全可以预测的。您可以准确地获得构造函数参数中提供的值。对于双字面0.1
“,正如您所引用的那样,传递给构造函数的值并不完全等于0.1
”。构造函数忠实地获取传入的值。可以预测。
答案 1 :(得分:3)
该程序说明了new BigDecimal(double)
构造函数的实际用法。目标是显示将舍入到给定双精度的精确结果的范围。这取决于能否获得具有双精确值的BigDecimal。
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
System.out.println(range(1.0));
System.out.println(range(Math.nextUp(1.0)));
System.out.println(range(Math.PI));
}
private static String range(double d){
BigDecimal down = new BigDecimal(Math.nextDown(d));
BigDecimal up = new BigDecimal(Math.nextUp(d));
BigDecimal bd = new BigDecimal(d);
BigDecimal halfUp = midPoint(bd, up);
BigDecimal halfDown = midPoint(down, bd);
Boolean isEven = (Double.doubleToLongBits(d) & 1) == 0;
if(isEven){
return "[" + halfDown + "," + halfUp + "]";
} else {
return "(" + halfDown + "," + halfUp + ")";
}
}
private static BigDecimal midPoint(BigDecimal low, BigDecimal high){
return low.add(high).divide(BigDecimal.valueOf(2));
}
}