code.vegaprotocol.io/vega@v0.79.0/libs/num/decimal.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package num 17 18 import ( 19 "errors" 20 "math/big" 21 22 "github.com/shopspring/decimal" 23 ) 24 25 type Decimal = decimal.Decimal 26 27 var ( 28 dzero = decimal.Zero 29 d1 = decimal.NewFromFloat(1) 30 dm1 = decimal.NewFromFloat(-1) 31 d2 = decimal.NewFromFloat(2) 32 maxDecimal = decimal.NewFromBigInt(maxU256, 0) 33 e = MustDecimalFromString("2.7182818285") 34 ) 35 36 func MustDecimalFromString(f string) Decimal { 37 d, err := DecimalFromString(f) 38 if err != nil { 39 panic(err) 40 } 41 return d 42 } 43 44 func DecimalOne() Decimal { 45 return d1 46 } 47 48 func DecimalMinusOne() Decimal { 49 return dm1 50 } 51 52 func DecimalTwo() Decimal { 53 return d2 54 } 55 56 func DecimalZero() Decimal { 57 return dzero 58 } 59 60 func DecimalE() Decimal { 61 return e 62 } 63 64 func MaxDecimal() Decimal { 65 return maxDecimal 66 } 67 68 func NewDecimalFromFloat(f float64) Decimal { 69 return decimal.NewFromFloat(f) 70 } 71 72 func NewDecimalFromBigInt(value *big.Int, exp int32) Decimal { 73 return decimal.NewFromBigInt(value, exp) 74 } 75 76 func DecimalFromUint(u *Uint) Decimal { 77 return decimal.NewFromUint(&u.u) 78 } 79 80 func DecimalFromInt(u *Int) Decimal { 81 d := decimal.NewFromUint(&u.U.u) 82 if u.IsNegative() { 83 return d.Neg() 84 } 85 return d 86 } 87 88 func DecimalFromInt64(i int64) Decimal { 89 return decimal.NewFromInt(i) 90 } 91 92 func DecimalFromFloat(v float64) Decimal { 93 return decimal.NewFromFloat(v) 94 } 95 96 func DecimalFromString(s string) (Decimal, error) { 97 return decimal.NewFromString(s) 98 } 99 100 func DecimalPart(a Decimal) Decimal { 101 return a.Sub(a.Floor()) 102 } 103 104 func MaxD(a, b Decimal) Decimal { 105 if a.GreaterThan(b) { 106 return a 107 } 108 return b 109 } 110 111 func MinD(a, b Decimal) Decimal { 112 if a.LessThan(b) { 113 return a 114 } 115 return b 116 } 117 118 // calculates the mean of a given slice. 119 func Mean(numbers []Decimal) (Decimal, error) { 120 if len(numbers) == 0 { 121 return DecimalZero(), errors.New("cannot calculate the mean of an empty list") 122 } 123 total := DecimalZero() 124 for _, num := range numbers { 125 total = total.Add(num) 126 } 127 return total.Div(DecimalFromInt64(int64(len(numbers)))), nil 128 } 129 130 // calculates the variance of a decimal slice. 131 func Variance(numbers []Decimal) (Decimal, error) { 132 if len(numbers) == 0 { 133 return DecimalZero(), errors.New("cannot calculate the variance of an empty list") 134 } 135 m, _ := Mean(numbers) 136 total := DecimalZero() 137 for _, num := range numbers { 138 total = total.Add(num.Sub(m).Pow(d2)) 139 } 140 return total.Div(DecimalFromInt64(int64(len(numbers)))), nil 141 } 142 143 func UnmarshalBinaryDecimal(data []byte) (Decimal, error) { 144 d := decimal.New(0, 1) 145 err := d.UnmarshalBinary(data) 146 return d, err 147 }