一提到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);
- }
- }
输出:
- 10.123
- 10.1229999999999993320898283855058252811431884765625
所以我们在选择构造函数时,要看具体需求而定。
另外,很多人会问到怎么将基本类型,如int,float,double,long,和BigDecimal对象相互转换。很简单:
基本类型通过构造函数转换成对应的BigDecimal对象,而BigDecimal类提供了诸如intValue(), floatValue(), doubleValue(), longValue()方法来将BigDecimal对象转换成对应的值。
关于BigDecimal是如何计算的,我以论坛中一个人的提问帖子为例,来简单的写出BigDecimal的运算方法。题目是:李白无事街上走,提壶去买酒。遇店加一倍,见花喝一斗,五遇花和店,喝光壶中酒,试问李白壶中原有多少斗酒?
这道题应该是从后往前推,并且要逆运算,最后得出原有酒的体积。
- import java.math.*;
- public class Libai {
- public static void main(String args[]){
- BigDecimal volumn = new BigDecimal("0");
- for (int i=0; i<5; i++){
- volumn = volumn.add(new BigDecimal("1"));
- volumn = volumn.divide(new BigDecimal("2"));
- }
- System.out.print(volumn);
- }
- }
结果:
- 0.96875