示例
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 aBigDecimal
which 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
String
constructor, on the other hand, is perfectly predictable: writingnew BigDecimal("0.1")
creates aBigDecimal
which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that theString
constructor be used in preference to this one. - When a
double
must be used as a source for aBigDecimal
, note that this constructor provides an exact conversion; it does not give the same result as converting thedouble
to aString
using theDouble.toString(double)
method and then using theBigDecimal(String)
constructor. To get that result, use thestatic
valueOf(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);
}
运行结果如下: