一:简介
Java中的简单浮点数类型float和double不能够进行运算,或者运算会丢失精度,不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal
<code> @Test
public
void
testDouble
(){ System.out
.println(0.05
+0.01
); System.out
.println(1.0
-0.42
); System.out
.println(4.015
*100
); System.out
.println(123.3
/100
); System.out
.println(Math.round(4.015
*100
)/100.0
); }/<code>
二:BigDecimal
BigDecimal有多种构造函数,常用的有2种,其中有一种不建议使用,就是double构造方式,建议使用String构造方式。
<code>public
BigDecimal
(String val)
;public
BigDecimal
(
double
val);/<code>
<code>BigDecimal也定义了几个常用的值,0
、1
、10
,静态的,可以通过类名直接引用BigDecimal.ZEROpublic
static
final
BigDecimal ZERO = zeroThroughTen[0
];public
static
final
BigDecimal ONE = zeroThroughTen[1
];public
static
final
BigDecimal TEN = zeroThroughTen[10
]; 三:工具类/<code>
由于构造方法要用String对应的构造方法,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后构造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类来简化操作。
<code>import
java.math.BigDecimal;public
class
ArithUtil
{private
static
final
int
DEF_DIV_SCALE =10
;public
static
double
add
(
double
v1,double
v2){ BigDecimal b1 =new
BigDecimal(Double.toString(v1)); BigDecimal b2 =new
BigDecimal(Double.toString(v2));return
b1.add(b2).doubleValue(); }public
static
double
sub
(
double
v1,double
v2){ BigDecimal b1 =new
BigDecimal(Double.toString(v1)); BigDecimal b2 =new
BigDecimal(Double.toString(v2));return
b1.subtract(b2).doubleValue(); }public
static
double
mul
(
double
v1,double
v2){ BigDecimal b1 =new
BigDecimal(Double.toString(v1)); BigDecimal b2 =new
BigDecimal(Double.toString(v2));return
b1.multiply(b2).doubleValue(); }public
static
double
div
(
double
v1,double
v2){return
div(v1,v2,DEF_DIV_SCALE); }public
static
double
div
(
double
v1,double
v2,int
scale){if
(scale<0
){throw
new
IllegalArgumentException("The scale must be a positive integer or zero"
); } BigDecimal b1 =new
BigDecimal(Double.toString(v1)); BigDecimal b2 =new
BigDecimal(Double.toString(v2));return
b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); }public
static
double
round
(
double
v,int
scale){if
(scale<0
){throw
new
IllegalArgumentException("The scale must be a positive integer or zero"
); } BigDecimal b =new
BigDecimal(Double.toString(v)); BigDecimal one =new
BigDecimal("1"
);return
b.divide(one,scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } }/<code>
四:测试
<code>@Test
public
void
testBigDecimal
(){ BigDecimal price = BigDecimal.ZERO; BigDecimal amount =new
BigDecimal("6.66"
); System.out
.println(ArithUtil.add
(0.05
,0.01
)); System.out
.println(ArithUtil.sub(1.0
,0.42
)); System.out
.println(ArithUtil.mul(4.015
,100
)); System.out
.println(ArithUtil.div(123.3
,100
)); System.out
.println(ArithUtil.round(4.015
,2
)); }/<code>