|
1 | | -package fpdecimal |
| 1 | +package fp3 |
2 | 2 |
|
3 | | -// Decimal is a decimal with fixed number of fraction digits. |
4 | | -// By default, uses 3 fractional digits. |
5 | | -// For example, values with 3 fractional digits will fit in ~9 quadrillion. |
| 3 | +import "github.com/nikolaydubina/fpdecimal" |
| 4 | + |
| 5 | +// Decimal with 3 fractional digits. |
6 | 6 | // Fractions lower than that are discarded in operations. |
7 | 7 | // Max: +9223372036854775.807 |
8 | 8 | // Min: -9223372036854775.808 |
9 | 9 | type Decimal struct{ v int64 } |
10 | 10 |
|
11 | 11 | var Zero = Decimal{} |
12 | 12 |
|
13 | | -var multipliers = [...]int64{1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000} |
14 | | - |
15 | 13 | type integer interface { |
16 | 14 | int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 |
17 | 15 | } |
18 | 16 |
|
19 | | -// FractionDigits that operations will use. |
20 | | -// Warning, after change, existing variables are not updated. |
21 | | -// Likely you want to use this once per runtime and in `func init()`. |
22 | | -var FractionDigits uint8 = 3 |
| 17 | +const ( |
| 18 | + fractionDigits = 3 |
| 19 | + multiplier = 1000 |
| 20 | +) |
23 | 21 |
|
24 | | -func FromInt[T integer](v T) Decimal { return Decimal{int64(v) * multipliers[FractionDigits]} } |
| 22 | +func FromInt[T integer](v T) Decimal { return Decimal{int64(v) * multiplier} } |
25 | 23 |
|
26 | 24 | func FromFloat[T float32 | float64](v T) Decimal { |
27 | | - return Decimal{int64(float64(v) * float64(multipliers[FractionDigits]))} |
| 25 | + return Decimal{int64(float64(v) * float64(multiplier))} |
28 | 26 | } |
29 | 27 |
|
30 | 28 | // FromIntScaled expects value already scaled to minor units |
31 | 29 | func FromIntScaled[T integer](v T) Decimal { return Decimal{int64(v)} } |
32 | 30 |
|
33 | 31 | func FromString(s string) (Decimal, error) { |
34 | | - v, err := ParseFixedPointDecimal([]byte(s), FractionDigits) |
| 32 | + v, err := fpdecimal.ParseFixedPointDecimal([]byte(s), fractionDigits) |
35 | 33 | return Decimal{v}, err |
36 | 34 | } |
37 | 35 |
|
38 | 36 | func (v *Decimal) UnmarshalJSON(b []byte) (err error) { |
39 | | - v.v, err = ParseFixedPointDecimal(b, FractionDigits) |
| 37 | + v.v, err = fpdecimal.ParseFixedPointDecimal(b, fractionDigits) |
40 | 38 | return err |
41 | 39 | } |
42 | 40 |
|
43 | 41 | func (v Decimal) MarshalJSON() ([]byte, error) { return []byte(v.String()), nil } |
44 | 42 |
|
45 | 43 | func (a Decimal) Scaled() int64 { return a.v } |
46 | 44 |
|
47 | | -func (a Decimal) Float32() float32 { return float32(a.v) / float32(multipliers[FractionDigits]) } |
| 45 | +func (a Decimal) Float32() float32 { return float32(a.v) / float32(multiplier) } |
48 | 46 |
|
49 | | -func (a Decimal) Float64() float64 { return float64(a.v) / float64(multipliers[FractionDigits]) } |
| 47 | +func (a Decimal) Float64() float64 { return float64(a.v) / float64(multiplier) } |
50 | 48 |
|
51 | | -func (a Decimal) String() string { return FixedPointDecimalToString(a.v, FractionDigits) } |
| 49 | +func (a Decimal) String() string { return fpdecimal.FixedPointDecimalToString(a.v, fractionDigits) } |
52 | 50 |
|
53 | 51 | func (a Decimal) Add(b Decimal) Decimal { return Decimal{v: a.v + b.v} } |
54 | 52 |
|
55 | 53 | func (a Decimal) Sub(b Decimal) Decimal { return Decimal{v: a.v - b.v} } |
56 | 54 |
|
57 | | -func (a Decimal) Mul(b Decimal) Decimal { return Decimal{v: a.v * b.v / multipliers[FractionDigits]} } |
| 55 | +func (a Decimal) Mul(b Decimal) Decimal { return Decimal{v: a.v * b.v / multiplier} } |
58 | 56 |
|
59 | | -func (a Decimal) Div(b Decimal) Decimal { return Decimal{v: a.v * multipliers[FractionDigits] / b.v} } |
| 57 | +func (a Decimal) Div(b Decimal) Decimal { return Decimal{v: a.v * multiplier / b.v} } |
60 | 58 |
|
61 | | -func (a Decimal) Mod(b Decimal) Decimal { return Decimal{v: a.v % (b.v / multipliers[FractionDigits])} } |
| 59 | +func (a Decimal) Mod(b Decimal) Decimal { return Decimal{v: a.v % (b.v / multiplier)} } |
62 | 60 |
|
63 | 61 | func (a Decimal) DivMod(b Decimal) (part, remainder Decimal) { return a.Div(b), a.Mod(b) } |
64 | 62 |
|
|
0 commit comments