Java中的簡單浮點數類型float和double不能夠進行精確運算。
請看下面實例:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
在《Effective Java》這本書中也提到這個原則,float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用java.math.BigDecimal。
我們如果需要精確計算,非要用String來夠造BigDecimal不可!
下面的這個工具類是是轉載別人的,可以通過個工具類實現小數的精確計算。
請看下面實例:
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
其運行結果如下:
2

3

4

5

6

7

8

9

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
在《Effective Java》這本書中也提到這個原則,float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用java.math.BigDecimal。
我們如果需要精確計算,非要用String來夠造BigDecimal不可!
下面的這個工具類是是轉載別人的,可以通過個工具類實現小數的精確計算。
1
import java.math.BigDecimal;
2
/**
3
* 由于Java的簡單類型不能夠精確的對浮點數進行運算,這個工具類提供精
4
* 確的浮點數運算,包括加減乘除和四舍五入。
5
*/
6
public class Arith{
7
//默認除法運算精度
8
private static final int DEF_DIV_SCALE = 10;
9
//這個類不能實例化
10
private Arith(){
11
}
12
13
/**
14
* 提供精確的加法運算。
15
* @param v1 被加數
16
* @param v2 加數
17
* @return 兩個參數的和
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
* 提供精確的減法運算。
26
* @param v1 被減數
27
* @param v2 減數
28
* @return 兩個參數的差
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
* 提供精確的乘法運算。
37
* @param v1 被乘數
38
* @param v2 乘數
39
* @return 兩個參數的積
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
* 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到
49
* 小數點以后10位,以后的數字四舍五入。
50
* @param v1 被除數
51
* @param v2 除數
52
* @return 兩個參數的商
53
*/
54
public static double div(double v1,double v2){
55
return div(v1,v2,DEF_DIV_SCALE);
56
}
57
58
/**
59
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指
60
* 定精度,以后的數字四舍五入。
61
* @param v1 被除數
62
* @param v2 除數
63
* @param scale 表示表示需要精確到小數點以后幾位。
64
* @return 兩個參數的商
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
* 提供精確的小數位四舍五入處理。
78
* @param v 需要四舍五入的數字
79
* @param scale 小數點后保留幾位
80
* @return 四舍五入后的結果
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
