github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/encoding/fixedn/fixed8.go (about) 1 package fixedn 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/nspcc-dev/neo-go/pkg/io" 8 ) 9 10 const ( 11 precision = 8 12 decimals = 100000000 13 ) 14 15 // Fixed8 represents a fixed-point number with precision 10^-8. 16 type Fixed8 int64 17 18 // String implements the Stringer interface. 19 func (f Fixed8) String() string { 20 buf := new(strings.Builder) 21 val := int64(f) 22 if val < 0 { 23 buf.WriteRune('-') 24 val = -val 25 } 26 str := strconv.FormatInt(val/decimals, 10) 27 buf.WriteString(str) 28 val %= decimals 29 if val > 0 { 30 buf.WriteRune('.') 31 str = strconv.FormatInt(val, 10) 32 for i := len(str); i < 8; i++ { 33 buf.WriteRune('0') 34 } 35 buf.WriteString(strings.TrimRight(str, "0")) 36 } 37 return buf.String() 38 } 39 40 // FloatValue returns the original value representing Fixed8 as float64. 41 func (f Fixed8) FloatValue() float64 { 42 return float64(f) / decimals 43 } 44 45 // IntegralValue returns an integer part of the original value representing 46 // Fixed8 as int64. 47 func (f Fixed8) IntegralValue() int64 { 48 return int64(f) / decimals 49 } 50 51 // FractionalValue returns a decimal part of the original value. It has the same 52 // sign as f, so that f = f.IntegralValue() + f.FractionalValue(). 53 func (f Fixed8) FractionalValue() int32 { 54 return int32(int64(f) % decimals) 55 } 56 57 // Fixed8FromInt64 returns a new Fixed8 type multiplied by decimals. 58 func Fixed8FromInt64(val int64) Fixed8 { 59 return Fixed8(decimals * val) 60 } 61 62 // Fixed8FromFloat returns a new Fixed8 type multiplied by decimals. 63 func Fixed8FromFloat(val float64) Fixed8 { 64 return Fixed8(int64(decimals * val)) 65 } 66 67 // Fixed8FromString parses s which must be a fixed point number 68 // with precision up to 10^-8. 69 func Fixed8FromString(s string) (Fixed8, error) { 70 num, err := FromString(s, precision) 71 if err != nil { 72 return 0, err 73 } 74 return Fixed8(num.Int64()), err 75 } 76 77 // UnmarshalJSON implements the json unmarshaller interface. 78 func (f *Fixed8) UnmarshalJSON(data []byte) error { 79 if len(data) > 2 { 80 if data[0] == '"' && data[len(data)-1] == '"' { 81 data = data[1 : len(data)-1] 82 } 83 } 84 return f.setFromString(string(data)) 85 } 86 87 // UnmarshalYAML implements the yaml unmarshaler interface. 88 func (f *Fixed8) UnmarshalYAML(unmarshal func(any) error) error { 89 var s string 90 err := unmarshal(&s) 91 if err != nil { 92 return err 93 } 94 return f.setFromString(s) 95 } 96 97 func (f *Fixed8) setFromString(s string) error { 98 p, err := Fixed8FromString(s) 99 if err != nil { 100 return err 101 } 102 *f = p 103 return nil 104 } 105 106 // MarshalJSON implements the json marshaller interface. 107 func (f Fixed8) MarshalJSON() ([]byte, error) { 108 return []byte(`"` + f.String() + `"`), nil 109 } 110 111 // MarshalYAML implements the yaml marshaller interface. 112 func (f Fixed8) MarshalYAML() (any, error) { 113 return f.String(), nil 114 } 115 116 // DecodeBinary implements the io.Serializable interface. 117 func (f *Fixed8) DecodeBinary(r *io.BinReader) { 118 *f = Fixed8(r.ReadU64LE()) 119 } 120 121 // EncodeBinary implements the io.Serializable interface. 122 func (f *Fixed8) EncodeBinary(w *io.BinWriter) { 123 w.WriteU64LE(uint64(*f)) 124 } 125 126 // Satoshi defines the value of a 'Satoshi'. 127 func Satoshi() Fixed8 { 128 return Fixed8(1) 129 } 130 131 // Div implements Fixd8 division operator. 132 func (f Fixed8) Div(i int64) Fixed8 { 133 return f / Fixed8FromInt64(i) 134 } 135 136 // Add implements Fixd8 addition operator. 137 func (f Fixed8) Add(g Fixed8) Fixed8 { 138 return f + g 139 } 140 141 // Sub implements Fixd8 subtraction operator. 142 func (f Fixed8) Sub(g Fixed8) Fixed8 { 143 return f - g 144 } 145 146 // LessThan implements Fixd8 < operator. 147 func (f Fixed8) LessThan(g Fixed8) bool { 148 return f < g 149 } 150 151 // GreaterThan implements Fixd8 < operator. 152 func (f Fixed8) GreaterThan(g Fixed8) bool { 153 return f > g 154 } 155 156 // Equal implements Fixd8 == operator. 157 func (f Fixed8) Equal(g Fixed8) bool { 158 return f == g 159 } 160 161 // CompareTo returns the difference between the f and g. 162 // difference < 0 implies f < g. 163 // difference = 0 implies f = g. 164 // difference > 0 implies f > g. 165 func (f Fixed8) CompareTo(g Fixed8) int { 166 return int(f - g) 167 }