一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法进行精确计算。但是Java的设计者给编程人员提供了一个很有用的类BigDecimal,他可以完善float和double类无法进行精确计算的缺憾。BigDecimal类位于java.maths类包下。首先我们来看下如何构造一个BigDecimal对象。它的构造函数很多,我挑最常用的两个来演示一下:一个就是BigDecimal(double val),另一个就是BigDecimal(String str)。这两个看上去没什么太大区别,但是正像API描述中说的那样:
/*The results of this constructor can be somewhat unpredictable. One might assume that
new BigDecimal(.1) is exactly equal to .1, but it is actually equal
to .1000000000000000055511151231257827021181583404541015625. This is so because .1
cannot be represented exactly as a double (or, for that matter, as a binary fraction
of any finite length). Thus, the long value that is being passed in to the constructor
is not exactly equal to .1, appearances nonwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal
(".1") is exactly equal to .1, as one would expect. Therefore, it is generally
recommended that the (String) constructor be used in preference to this one.*/
也就是说利用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。而利用String对象作为参数传入的构造函数能精确的构造出一个BigDecimal对象。请看下面的代码:
import java.math.*;
public class TestBigDecimal {
public static void main(String args[]){
BigDecimal bd = new BigDecimal("10.123");
BigDecimal bd1 = new BigDecimal(10.123);
System.out.println(bd +"/n"+ bd1);
}
}
输出:
view plaincopy to clipboardprint?
10.123
10.1229999999999993320898283855058252811431884765625
所以我们在选择构造函数时,要看具体需求而定。
另外,很多人会问到怎么将基本类型,如int,float,double,long,和BigDecimal对象相互转换。很简单:
基本类型通过构造函数转换成对应的BigDecimal对象,而BigDecimal类提供了诸如intValue(), floatValue(), doubleValue(), longValue()方法来将BigDecimal对象转换成对应的值。
关于BigDecimal是如何计算的,我以论坛中一个人的提问帖子为例,来简单的写出BigDecimal的运算方法。题目是:李白无事街上走,提壶去买酒。遇店加一倍,见花喝一斗,五遇花和店,喝光壶中酒,试问李白壶中原有多少斗酒?
这道题应该是从后往前推,并且要逆运算,最后得出原有酒的体积。
view plaincopy to clipboardprint?
import java.math.*;
public class Libai {
public static void main(String args[]){
BigDecimal volumn = new BigDecimal("0");
for (int i=0; i