7.3.6 BigDecimal类
float
、 double
这两个基本类型的浮点数容易引起精度丢失.
为了能精确表示、计算浮点数,Java
提供了BigDecimal
类,该类提供了大量的构造器用于创建BigDecimal
对象,包括把所有的基本数值型变量转换成一个BigDecimal
对象,也包括利用数字字符串
、数字字符数组
来创建BigDecimal
对象。
因为double
存在精度问题,所以调用BigDecimal
类是构造器时中应该传入字符串值,不要传入double
值。
如果必须使用double
浮点数作为BigDecimal
构造器的参数时,不要直接将该double
浮点数作为构造器参数来创建BigDecimal
对象,而是应该通过BigDecimal.valueOf(double value)
静态方法来创建BigDecimal
对象。
BigDecimal
类提供了add()
、 subtract()
、 multiply()
、 divide()
、pow()
等方法对精确浮点数进行常规算术运算。
实例
下面程序示范了BigDecimal
的基本运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.math.*;
public class BigDecimalTest { public static void main(String[] args) { BigDecimal f1 = new BigDecimal("0.05"); BigDecimal f2 = BigDecimal.valueOf(0.01);
BigDecimal f3 = new BigDecimal(0.05); System.out.println("使用String作为BigDecimal构造器参数:"); System.out.println("0.05 + 0.01 = " + f1.add(f2)); System.out.println("0.05 - 0.01 = " + f1.subtract(f2)); System.out.println("0.05 * 0.01 = " + f1.multiply(f2)); System.out.println("0.05 / 0.01 = " + f1.divide(f2)); System.out.println("使用double作为BigDecimal构造器参数:"); System.out.println("0.05 + 0.01 = " + f3.add(f2)); System.out.println("0.05 - 0.01 = " + f3.subtract(f2)); System.out.println("0.05 * 0.01 = " + f3.multiply(f2)); System.out.println("0.05 / 0.01 = " + f3.divide(f2)); } }
|
运行结果:
1 2 3 4 5 6 7 8 9 10
| 使用String作为BigDecimal构造器参数: 0.05 + 0.01 = 0.06 0.05 - 0.01 = 0.04 0.05 * 0.01 = 0.0005 0.05 / 0.01 = 5 使用double作为BigDecimal构造器参数: 0.05 + 0.01 = 0.06000000000000000277555756156289135105907917022705078125 0.05 - 0.01 = 0.04000000000000000277555756156289135105907917022705078125 0.05 * 0.01 = 0.0005000000000000000277555756156289135105907917022705078125 0.05 / 0.01 = 5.000000000000000277555756156289135105907917022705078125
|
创建BigDecimal
对象时,一定要使用String
对象作为构造器参数,而不是直接使用double
数字。
如何对double做精确的运算
如果程序中要求对double
浮点数进行加、减、乘、除基本运算,则需要:
- 先将
double
类型数值包装成BigDecimal
对象,
- 然后调用
BigDecimal
对象的方法执行运算
- 最后将结果转换成
double
型变量。
这是比较烦琐的过程,可以考虑以BigDecimal
为基础定义一个Arith
工具类来进行运行.
该工具类代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import java.math.*;
public class Arith { private static final int DEF_DIV_SCALE = 10;
private Arith() { }
public static double add(double v1, double v2) { BigDecimal b1 = BigDecimal.valueOf(v1); BigDecimal b2 = BigDecimal.valueOf(v2); return b1.add(b2).doubleValue(); }
public static double sub(double v1, double v2) { BigDecimal b1 = BigDecimal.valueOf(v1); BigDecimal b2 = BigDecimal.valueOf(v2); return b1.subtract(b2).doubleValue(); }
public static double mul(double v1, double v2) { BigDecimal b1 = BigDecimal.valueOf(v1); BigDecimal b2 = BigDecimal.valueOf(v2); return b1.multiply(b2).doubleValue(); }
public static double div(double v1, double v2) { BigDecimal b1 = BigDecimal.valueOf(v1); BigDecimal b2 = BigDecimal.valueOf(v2); return b1.divide(b2, DEF_DIV_SCALE, RoundingMode.HALF_UP).doubleValue(); }
public static void main(String[] args) { System.out.println("0.05 + 0.01 = " + Arith.add(0.05, 0.01)); System.out.println("1.0 - 0.42 = " + Arith.sub(1.0, 0.42)); System.out.println("4.015 * 100 = " + Arith.mul(4.015, 100)); System.out.println("123.3 / 100 = " + Arith.div(123.3, 100)); } }
|
运行上面程序将看到如下运行结果:
1 2 3 4
| 0.05 + 0.01 = 0.06 1.0 - 0.42 = 0.58 4.015 * 100 = 401.5 123.3 / 100 = 1.233
|