@@ -7,70 +7,117 @@ import (
7
7
"github.com/golang-plus/math/big"
8
8
)
9
9
10
- // Money represents an amount of a specific currency.
10
+ // Money represents an amount (with precision 4) of a specific currency.
11
11
type Money struct {
12
+ amount * big.Decimal
12
13
Currency * Currency
13
14
Amount float64
14
- decimal * big.Decimal
15
- }
16
-
17
- // NewMoney returns a new money.
18
- func NewMoney (currency * Currency , amount float64 ) (* Money , error ) {
19
- if currency == nil {
20
- return nil , errors .New ("currency of money cannot be nil" )
21
- }
22
-
23
- return & Money {
24
- Currency : currency ,
25
- Amount : amount ,
26
- decimal : big .NewDecimal (amount ),
27
- }, nil
28
- }
29
-
30
- // MustNewMoney is like as NewMoney but panic if error happens.
31
- func MustNewMoney (currency * Currency , amount float64 ) * Money {
32
- money , err := NewMoney (currency , amount )
33
- if err != nil {
34
- panic (err )
35
- }
36
-
37
- return money
38
15
}
39
16
40
17
// Format returns the formatted string of money.
41
18
func (m * Money ) Format (formatter * CurrencyFormatter ) string {
42
19
return formatter .Format (m .Amount )
43
20
}
44
21
45
- // String returns the string of money (format: currency code + amount).
22
+ // String returns the formatted string (format: currency code + amount).
46
23
func (m * Money ) String () string {
47
24
return fmt .Sprintf ("%s %f" , m .Currency .Code , m .Amount )
48
25
}
49
26
50
- // Add sets m.decimal to the sum of m.decimal and another and returns m.
27
+ // IsZero reports whether the amount is euqal to zero.
28
+ func (m * Money ) IsZero () bool {
29
+ return m .amount .IsZero ()
30
+ }
31
+
32
+ // Sign returns:
33
+ // -1: if m < 0
34
+ // 0: if m == 0
35
+ // +1: if m > 0
36
+ func (m * Money ) Sign () int {
37
+ return m .amount .Sign ()
38
+ }
39
+
40
+ // Add sets amount to the sum of amount and x then returns m.
51
41
func (m * Money ) Add (x float64 ) * Money {
52
- m .decimal .Add (big .NewDecimal (x ))
53
- m .Amount = m .decimal .Float64 ()
42
+ m .amount .Add (big .NewDecimal (x ))
43
+ m .Amount , _ = m .amount .Float64 ()
54
44
return m
55
45
}
56
46
57
- // Sub sets m.decimal to the difference m.decimal-another and returns m.
47
+ // Sub sets amount to the difference amount-x then returns m.
58
48
func (m * Money ) Sub (x float64 ) * Money {
59
- m .decimal .Sub (big .NewDecimal (x ))
60
- m .Amount = m .decimal .Float64 ()
49
+ m .amount .Sub (big .NewDecimal (x ))
50
+ m .Amount , _ = m .amount .Float64 ()
61
51
return m
62
52
}
63
53
64
- // Mul sets m.decimal to the product m.decimal*another and returns m.
54
+ // Mul sets amount to the product amount*x and returns m.
65
55
func (m * Money ) Mul (x float64 ) * Money {
66
- m .decimal .Mul (big .NewDecimal (x ))
67
- m .Amount = m .decimal .Float64 ()
56
+ m .amount .Mul (big .NewDecimal (x ))
57
+ m .Amount , _ = m .amount .Float64 ()
68
58
return m
69
59
}
70
60
71
- // Div sets m.decimal to the quotient m/another and return m.
61
+ // Div sets amount to the quotient amount/x and return m.
72
62
func (m * Money ) Div (x float64 ) * Money {
73
- m .decimal .Div (big .NewDecimal (x ))
74
- m .Amount = m .decimal .Float64 ()
63
+ m .amount .Div (big .NewDecimal (x ))
64
+ m .Amount , _ = m .amount .Float64 ()
75
65
return m
76
66
}
67
+
68
+ // RoundToNearestEven rounds the amount by "To Nearest Even" mode with 4 precision.
69
+ // precision indicates the number of digits after the decimal point.
70
+ func (m * Money ) RoundToNearestEven (precision uint ) * Money {
71
+ m .amount .RoundToNearestEven (precision )
72
+ m .Amount , _ = m .amount .Float64 ()
73
+ return m
74
+ }
75
+
76
+ // RoundToNearestEven rounds the amount by "To Nearest Away From Zero" mode with 4 precision.
77
+ // precision indicates the number of digits after the decimal point.
78
+ func (m * Money ) RoundToNearestAway (precision uint ) * Money {
79
+ m .amount .RoundToNearestAway (precision )
80
+ m .Amount , _ = m .amount .Float64 ()
81
+ return m
82
+ }
83
+
84
+ // RoundToZero rounds the amount by "To Zero" mode with 4 precision.
85
+ // precision indicates the number of digits after the decimal point.
86
+ func (m * Money ) RoundToZero (precision uint ) * Money {
87
+ m .amount .RoundToZero (precision )
88
+ m .Amount , _ = m .amount .Float64 ()
89
+ return m
90
+ }
91
+
92
+ // Round is same as RoundToNearestEven.
93
+ func (m * Money ) Round (precision uint ) * Money {
94
+ return m .RoundToNearestEven (precision )
95
+ }
96
+
97
+ // Truncate is same as RoundToZero.
98
+ func (m * Money ) Truncate (precision uint ) * Money {
99
+ return m .RoundToZero (precision )
100
+ }
101
+
102
+ // NewMoney returns a new money.
103
+ func NewMoney (currency * Currency , amount float64 ) (* Money , error ) {
104
+ if currency == nil {
105
+ return nil , errors .New ("currency of money cannot be nil" )
106
+ }
107
+
108
+ return & Money {
109
+ amount : big .NewDecimal (amount ),
110
+ Currency : currency ,
111
+ Amount : amount ,
112
+ }, nil
113
+ }
114
+
115
+ // MustNewMoney is like as NewMoney but panic if error happens.
116
+ func MustNewMoney (currency * Currency , amount float64 ) * Money {
117
+ money , err := NewMoney (currency , amount )
118
+ if err != nil {
119
+ panic (err )
120
+ }
121
+
122
+ return money
123
+ }
0 commit comments