BigDecimal是Java提供的一个不变的、任意精度的有符号十进制数对象。提供的方法如下:
序号 | 方 法 | 类型 | 描 述 |
1 | public BigDecimal(double val) | 构造 | 将double表示形式转换 为BigDecimal |
2 | public BigDecimal(int val) | 构造 | 将int表示形式转换为 BigDecimal |
3 | public BigDecimal(String val) | 构造 | 将字符串表示 形式转换为BigDecimal |
4 | public BigDecimal add(BigDecimal augend) | 普通 | 加法 |
5 | public BigDecimal subtract(BigDecimal | 普通 | 减法 |
6 | public BigDecimal multiply(BigDecimal | 普通 | 乘法 |
7 | public BigDecimal divide(BigDecimal | 普通 | 除法 |
它提供了四个构造器,我们重点看用double和String构造的两个构造器(有关BigInteger详细介绍请查阅j2se API文档)。
BigDecimal(double val) |
BigDecimal(String val) |
BigDecimal(double)是把一个double类型十进制数构造为一个BigDecimal对象实例。
BigDecimal(String)是把一个以String表示的BigDecimal对象构造为BigDecimal对象实例。
习惯上,对于浮点数我们都会定义为double或float,但BigDecimal API文档中对于BigDecimal(double)有这么一段话:
- /*The results of this constructor can be somewhat unpredictable. One might assume that
- new BigDecimal(0.1) is exactly equal to 0.1, but it is actually equal
- to .1000000000000000055511151231257827021181583404541015625. This is so because 0.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 0.1, appearances nonwithstanding.
- The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal
- ("0.1") is exactly equal to0 .1, as one would expect. Therefore, it is generally
- recommended that the (String) constructor be used in preference to this one.*/
下面对这段话做简单解释:
注意:这个构造器的结果可能会有不可预知的结果。
有人可能设想new BigDecimal(0.1)等于0.1是正确的,但它实际上是等于0.100000000000000005551115
然而(String)构造器,则完全可预知的,new BigDecimal(“0.1”)如同期望的那样精确的等于0.1,因此,(String)构造器是被优先推荐使用的。
- 当 double 必须用作BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用
Double.toString(double)
方法,然后使用BigDecimal(String)
构造方法,将double 转换为 String。要获取该结果,请使用staticvalueOf(double)
方法。看下面的结果:
System.out.println(new BigDecimal(123456789.02).toString()); System.out.println(new BigDecimal("123456789.02").toString()); 输出为:
123456789.019999995827674865722656
25 123456789.02
现在我们知道,如果需要精确计算,非要用String来够造BigDecimal不可!
实现方案
现在我们已经知道怎么解决这个问题了,原则上是使用BigDecimal(String)构造器,我们建议,在商业应用开发中,涉及金额等浮点数计算的数据,全部定义为String,数据库中可定义为字符型字段,在需要使用这些数据进行运算的时候,使用BigDecimal(String)构造BigDecimal对象进行运算,保证数据的精确计算。