Java中的簡單浮點(diǎn)數(shù)類型float和double不能夠進(jìn)行精確運(yùn)算。
請看下面實(shí)例:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
在《Effective Java》這本書中也提到這個(gè)原則,float和double只能用來做科學(xué)計(jì)算或者是工程計(jì)算,在商業(yè)計(jì)算中我們要用java.math.BigDecimal。
我們?nèi)绻枰_計(jì)算,非要用String來夠造BigDecimal不可!
下面的這個(gè)工具類是是轉(zhuǎn)載別人的,可以通過個(gè)工具類實(shí)現(xiàn)小數(shù)的精確計(jì)算。
請看下面實(shí)例:
1
public class Test{
2
public static void main(String args[]){
3
System.out.println(0.05+0.01);
4
System.out.println(1.0-0.42);
5
System.out.println(4.015*100);
6
System.out.println(123.3/100);
7
}
8
}
9
其運(yùn)行結(jié)果如下:
2

3

4

5

6

7

8

9

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
在《Effective Java》這本書中也提到這個(gè)原則,float和double只能用來做科學(xué)計(jì)算或者是工程計(jì)算,在商業(yè)計(jì)算中我們要用java.math.BigDecimal。
我們?nèi)绻枰_計(jì)算,非要用String來夠造BigDecimal不可!
下面的這個(gè)工具類是是轉(zhuǎn)載別人的,可以通過個(gè)工具類實(shí)現(xiàn)小數(shù)的精確計(jì)算。
1
import java.math.BigDecimal;
2
/**
3
* 由于Java的簡單類型不能夠精確的對浮點(diǎn)數(shù)進(jìn)行運(yùn)算,這個(gè)工具類提供精
4
* 確的浮點(diǎn)數(shù)運(yùn)算,包括加減乘除和四舍五入。
5
*/
6
public class Arith{
7
//默認(rèn)除法運(yùn)算精度
8
private static final int DEF_DIV_SCALE = 10;
9
//這個(gè)類不能實(shí)例化
10
private Arith(){
11
}
12
13
/**
14
* 提供精確的加法運(yùn)算。
15
* @param v1 被加數(shù)
16
* @param v2 加數(shù)
17
* @return 兩個(gè)參數(shù)的和
18
*/
19
public static double add(double v1,double v2){
20
BigDecimal b1 = new BigDecimal(Double.toString(v1));
21
BigDecimal b2 = new BigDecimal(Double.toString(v2));
22
return b1.add(b2).doubleValue();
23
}
24
/**
25
* 提供精確的減法運(yùn)算。
26
* @param v1 被減數(shù)
27
* @param v2 減數(shù)
28
* @return 兩個(gè)參數(shù)的差
29
*/
30
public static double sub(double v1,double v2){
31
BigDecimal b1 = new BigDecimal(Double.toString(v1));
32
BigDecimal b2 = new BigDecimal(Double.toString(v2));
33
return b1.subtract(b2).doubleValue();
34
}
35
/**
36
* 提供精確的乘法運(yùn)算。
37
* @param v1 被乘數(shù)
38
* @param v2 乘數(shù)
39
* @return 兩個(gè)參數(shù)的積
40
*/
41
public static double mul(double v1,double v2){
42
BigDecimal b1 = new BigDecimal(Double.toString(v1));
43
BigDecimal b2 = new BigDecimal(Double.toString(v2));
44
return b1.multiply(b2).doubleValue();
45
}
46
47
/**
48
* 提供(相對)精確的除法運(yùn)算,當(dāng)發(fā)生除不盡的情況時(shí),精確到
49
* 小數(shù)點(diǎn)以后10位,以后的數(shù)字四舍五入。
50
* @param v1 被除數(shù)
51
* @param v2 除數(shù)
52
* @return 兩個(gè)參數(shù)的商
53
*/
54
public static double div(double v1,double v2){
55
return div(v1,v2,DEF_DIV_SCALE);
56
}
57
58
/**
59
* 提供(相對)精確的除法運(yùn)算。當(dāng)發(fā)生除不盡的情況時(shí),由scale參數(shù)指
60
* 定精度,以后的數(shù)字四舍五入。
61
* @param v1 被除數(shù)
62
* @param v2 除數(shù)
63
* @param scale 表示表示需要精確到小數(shù)點(diǎn)以后幾位。
64
* @return 兩個(gè)參數(shù)的商
65
*/
66
public static double div(double v1,double v2,int scale){
67
if(scale<0){
68
throw new IllegalArgumentException(
69
"The scale must be a positive integer or zero");
70
}
71
BigDecimal b1 = new BigDecimal(Double.toString(v1));
72
BigDecimal b2 = new BigDecimal(Double.toString(v2));
73
return b1.divid(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
74
}
75
76
/**
77
* 提供精確的小數(shù)位四舍五入處理。
78
* @param v 需要四舍五入的數(shù)字
79
* @param scale 小數(shù)點(diǎn)后保留幾位
80
* @return 四舍五入后的結(jié)果
81
*/
82
public static double round(double v,int scale){
83
if(scale<0){
84
throw new IllegalArgumentException(
85
"The scale must be a positive integer or zero");
86
}
87
BigDecimal b = new BigDecimal(Double.toString(v));
88
BigDecimal one = new BigDecimal("1");
89
return b.divid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
90
}
91
}
92

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

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92
