示例
import java.math.BigDecimal;
public class BigDecimalDemo
{
static final int location=10;
public static void main(String[] args){
BigDecimalDemo b=new BigDecimalDemo();
System.out.println("两个数字相加结果是:"+b.add(-7.5,8.9));
System.out.println("两个数字相减结果是:"+b.sub(-7.5,8.9));
System.out.println("两个数字相乘结果是:"+b.mul(-7.5,8.9));
System.out.println("两个数字相除,小数点后保留10位,结果是:"+b.div(-7.5,8.9));
System.out.println("两个数字相除,小数点后保留5位,结果是:"+b.div(-7.5,8.9,5));
}
public BigDecimal add(double value1,double value2){
// BigDecimal b1=new BigDecimal(Double.toString(value1)); //Double.toString(value1)返回的String类的value1,原因见下。
// BigDecimal b2=new BigDecimal(Double.toString(value2));
BigDecimal b1=new BigDecimal(value1);
BigDecimal b2=new BigDecimal(value2);
return b1.add(b2);
}
public BigDecimal sub(double value1,double value2){
BigDecimal b1=new BigDecimal(Double.toString(value1));
BigDecimal b2=new BigDecimal(Double.toString(value2));
return b1.subtract(b2);
}
public BigDecimal mul(double value1,double value2){
BigDecimal b1=new BigDecimal(Double.toString(value1));
BigDecimal b2=new BigDecimal(Double.toString(value2));
return b1.multiply(b2);
}
public BigDecimal div(double value1,double value2){
return div(value1,value2,location);
}
public BigDecimal div(double value1,double value2,int b){
if(b<0){
System.out.println("b必须大于等于0");
}
BigDecimal b1=new BigDecimal(Double.toString(value1));
BigDecimal b2=new BigDecimal(Double.toString(value2));
return b1.divide(b2,b,BigDecimal.ROUND_HALF_UP);
}
}
运行结果如图:
为什么要使用Double.toString(double value1)作为形参,而不是直接使用double value1作为形参,修改前后两次运行,相加的结果为什么会有这么大的不同呢?直接在java API中找原因。
首先,看下Double.toString(double value)与double value有什么区别。
Double类中的toString方法说明如下:
toString
public static String toString(double d)
Returns a string representation of the
double argument. All characters mentioned below are ASCII characters. 其次,既然形参的类型确定了,就要看调用BigDecimal构造方法有什么不同了,这里主要涉及到了BigDecimal(double val)和BigDecimal(String val)两种,区别如下。
BigDecimal(String val)Translates the string representation of a
BigDecimal into a BigDecimal.将会把String型转换成BigDecimal.
BigDecimal(double val)Translates a
double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.将会把double型二进制浮点型值精确的转换成十进制的BigDecimal.(好难理解哦!)在BigDecimal(double val)中有如下的说明:
Notes:
- The results of this constructor can be somewhat unpredictable. One might assume that writing
new BigDecimal(0.1)in Java creates aBigDecimalwhich is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as adouble(or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. - The
Stringconstructor, on the other hand, is perfectly predictable: writingnew BigDecimal("0.1")creates aBigDecimalwhich is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that theStringconstructor be used in preference to this one. - When a
doublemust be used as a source for aBigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting thedoubleto aStringusing theDouble.toString(double)method and then using theBigDecimal(String)constructor. To get that result, use thestaticvalueOf(double)method.
1.这个构造函数的结果有点难以预测。你可能认为java中用new BigDecimal(0.1)创建的BigDecimal应该等于0.1(一个是1的无精度的值,一个是有精度的值),但实际上精确的是等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能被double精确的表示(作为任意限定长度的二进制小数,实在不明白什么意思)。因此,传入构造函数的值不是精确的等于0.1。
2.而String参数的构造函数就能够得到很好的预测:如同我们认为的那样,new BigDecimal("0.1")完全等于0.1.因此,建议优先使用BigDecimal(String val)构造函数。
3.如果必须将double型传入BigDecimal,要注意该构造函数是一个精确的转换,它无法得到与先调用Double.toString(double)方法将double转换成String,再使用BigDecimal(String)构造函数一样的结果。如果要达到这种结果,要使用静态valueOf(double)方法。
3.如果必须将double型传入BigDecimal,要注意该构造函数是一个精确的转换,它无法得到与先调用Double.toString(double)方法将double转换成String,再使用BigDecimal(String)构造函数一样的结果。如果要达到这种结果,要使用静态valueOf(double)方法。
对示例进行修改如下:
public BigDecimal add(double value1,double value2){
// BigDecimal b1=new BigDecimal(Double.toString(value1)); //Double.toString(value1)返回的是字符串value1
// BigDecimal b2=new BigDecimal(Double.toString(value2));
BigDecimal b1=BigDecimal.valueOf(value1);
BigDecimal b2=BigDecimal.valueOf(value2);
return b1.add(b2);
}
运行结果如下: