首先我們先來(lái)看如下代碼示例:
1
2
3
4
5
6
7
8
|
public class Test_1 { public static void main(String[] args) { System.out.println( 0.06 + 0.01 ); System.out.println( 1.0 - 0.42 ); System.out.println( 4.015 * 100 ); System.out.println( 303.1 / 1000 ); } } |
運(yùn)行結(jié)果如下。
0.06999999999999999
0.5800000000000001
401.49999999999994
0.30310000000000004
你認(rèn)為你看錯(cuò)了,但結(jié)果卻是是這樣的。問(wèn)題在哪里呢?原因在于我們的計(jì)算機(jī)是二進(jìn)制的。浮點(diǎn)數(shù)沒(méi)有辦法是用二進(jìn)制進(jìn)行精確表示。我們的CPU表示浮點(diǎn)數(shù)由兩個(gè)部分組成:指數(shù)和尾數(shù),這樣的表示方法一般都會(huì)失去一定的精確度,有些浮點(diǎn)數(shù)運(yùn)算也會(huì)產(chǎn)生一定的誤差。如:2.4的二進(jìn)制表示并非就是精確的2.4。反而最為接近的二進(jìn)制表示是 2.3999999999999999。浮點(diǎn)數(shù)的值實(shí)際上是由一個(gè)特定的數(shù)學(xué)公式計(jì)算得到的。
其實(shí)java的float只能用來(lái)進(jìn)行科學(xué)計(jì)算或工程計(jì)算,在大多數(shù)的商業(yè)計(jì)算中,一般采用java.math.BigDecimal類(lèi)來(lái)進(jìn)行精確計(jì)算。
在使用BigDecimal類(lèi)來(lái)進(jìn)行計(jì)算的時(shí)候,主要分為以下步驟:
1、用float或者double變量構(gòu)建BigDecimal對(duì)象。
2、通過(guò)調(diào)用BigDecimal的加,減,乘,除等相應(yīng)的方法進(jìn)行算術(shù)運(yùn)算。
3、把BigDecimal對(duì)象轉(zhuǎn)換成float,double,int等類(lèi)型。
一般來(lái)說(shuō),可以使用BigDecimal的構(gòu)造方法或者靜態(tài)方法的valueOf()方法把基本類(lèi)型的變量構(gòu)建成BigDecimal對(duì)象。
1
2
|
BigDecimal b1 = new BigDecimal(Double.toString( 0.48 )); BigDecimal b2 = BigDecimal.valueOf( 0.48 ); |
對(duì)于常用的加,減,乘,除,BigDecimal類(lèi)提供了相應(yīng)的成員方法。
1
2
3
4
|
public BigDecimal add(BigDecimal value); //加法 public BigDecimal subtract(BigDecimal value); //減法 public BigDecimal multiply(BigDecimal value); //乘法 public BigDecimal divide(BigDecimal value); //除法 |
進(jìn)行相應(yīng)的計(jì)算后,我們可能需要將BigDecimal對(duì)象轉(zhuǎn)換成相應(yīng)的基本數(shù)據(jù)類(lèi)型的變量,可以使用floatValue(),doubleValue()等方法。
下面是一個(gè)工具類(lèi),該工具類(lèi)提供加,減,乘,除運(yùn)算。
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
49
50
51
52
|
public class Arith { /** * 提供精確加法計(jì)算的add方法 * @param value1 被加數(shù) * @param value2 加數(shù) * @return 兩個(gè)參數(shù)的和 */ public static double add( double value1, double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.add(b2).doubleValue(); } /** * 提供精確減法運(yùn)算的sub方法 * @param value1 被減數(shù) * @param value2 減數(shù) * @return 兩個(gè)參數(shù)的差 */ public static double sub( double value1, double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.subtract(b2).doubleValue(); } /** * 提供精確乘法運(yùn)算的mul方法 * @param value1 被乘數(shù) * @param value2 乘數(shù) * @return 兩個(gè)參數(shù)的積 */ public static double mul( double value1, double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.multiply(b2).doubleValue(); } /** * 提供精確的除法運(yùn)算方法div * @param value1 被除數(shù) * @param value2 除數(shù) * @param scale 精確范圍 * @return 兩個(gè)參數(shù)的商 * @throws IllegalAccessException */ public static double div( double value1, double value2, int scale) throws IllegalAccessException{ //如果精確范圍小于0,拋出異常信息 if (scale< 0 ){ throw new IllegalAccessException( "精確度不能小于0" ); } BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.divide(b2, scale).doubleValue(); } } |
以上所述是小編給大家介紹的Java中使用BigDecimal進(jìn)行精確運(yùn)算,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
原文鏈接:http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html