code.vegaprotocol.io/vega@v0.79.0/libs/num/int.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 "database/sql/driver" 20 "fmt" 21 "math/big" 22 23 "github.com/holiman/uint256" 24 ) 25 26 var ( 27 ErrInvalidScanInput = fmt.Errorf("invalid input for Scan") 28 intZero = NewInt(0) 29 ) 30 31 // Int a wrapper to a signed big int. 32 type Int struct { 33 // The unsigned version of the integer 34 U *Uint 35 // The sign of the integer true = positive, false = negative 36 s bool 37 } 38 39 func IntFromUint(u *Uint, s bool) *Int { 40 return &Int{ 41 s: s, 42 U: u.Clone(), 43 } 44 } 45 46 func IntToString(u *Int) string { 47 if u != nil { 48 return u.String() 49 } 50 return "0" 51 } 52 53 // IntFromString creates a new Int from a string 54 // interpreted using the give base. 55 // A big.Int is used to read the string, so 56 // all error related to big.Int parsing applied here. 57 // will return true if an error happened. 58 func IntFromString(str string, base int) (*Int, bool) { 59 b, ok := big.NewInt(0).SetString(str, base) 60 if !ok { 61 return NewInt(0), true 62 } 63 return IntFromBig(b) 64 } 65 66 // IntFromBig construct a new Int with a big.Int 67 // returns true if overflow happened. 68 func IntFromBig(b *big.Int) (*Int, bool) { 69 positive := true 70 if b.Sign() < 0 { 71 b.Neg(b) 72 positive = false 73 } 74 75 u, overflow := uint256.FromBig(b) 76 if overflow { 77 return NewInt(0), true 78 } 79 return &Int{ 80 U: &Uint{*u}, 81 s: positive, 82 }, false 83 } 84 85 // IntFromDecimal returns the Int part of a decimal. 86 func IntFromDecimal(d Decimal) (*Int, bool) { 87 dd := d 88 89 // if its negative it'll overflow so need to negate before going to Uint 90 if d.IsNegative() { 91 dd = d.Neg() 92 } 93 u, overflow := dd.Uint() 94 return &Int{ 95 U: &Uint{*u}, 96 s: d.IsPositive(), 97 }, overflow 98 } 99 100 // IsNegative tests if the stored value is negative 101 // true if < 0 102 // false if >= 0. 103 func (i *Int) IsNegative() bool { 104 return !i.s && !i.U.IsZero() 105 } 106 107 // IsPositive tests if the stored value is positive 108 // true if > 0 109 // false if <= 0. 110 func (i *Int) IsPositive() bool { 111 return i.s && !i.U.IsZero() 112 } 113 114 // IsZero tests if the stored value is zero 115 // true if == 0. 116 func (i *Int) IsZero() bool { 117 return i.U.IsZero() 118 } 119 120 // FlipSign changes the sign of the number from - to + and back again. 121 func (i *Int) FlipSign() { 122 i.s = !i.s 123 } 124 125 // Clone creates a copy of the object so nothing is shared. 126 func (i Int) Clone() *Int { 127 return &Int{ 128 U: i.U.Clone(), 129 s: i.s, 130 } 131 } 132 133 func (i Int) EQ(o *Int) bool { 134 return i.s == o.s && i.U.EQ(o.U) 135 } 136 137 // GT returns if i > o. 138 func (i Int) GT(o *Int) bool { 139 if i.IsNegative() { 140 if o.IsPositive() || o.IsZero() { 141 return false 142 } 143 144 return i.U.LT(o.U) 145 } 146 if i.IsPositive() { 147 if o.IsZero() || o.IsNegative() { 148 return true 149 } 150 151 return i.U.GT(o.U) 152 } 153 154 return o.IsNegative() 155 } 156 157 func (i Int) GTE(o *Int) bool { 158 return i.GT(o) || i.EQ(o) 159 } 160 161 // LT returns if i < o. 162 func (i Int) LT(o *Int) bool { 163 if i.IsNegative() { 164 if o.IsPositive() || o.IsZero() { 165 return true 166 } 167 168 return i.U.GT(o.U) 169 } 170 if i.IsPositive() { 171 if o.IsZero() || o.IsNegative() { 172 return false 173 } 174 175 return i.U.LT(o.U) 176 } 177 178 return o.IsPositive() 179 } 180 181 func (i Int) LTE(o *Int) bool { 182 return i.LT(o) || i.EQ(o) 183 } 184 185 func (i Int) Int64() int64 { 186 val := int64(i.U.Uint64()) 187 if i.IsNegative() { 188 return -val 189 } 190 191 return val 192 } 193 194 // String returns a string version of the number. 195 func (i Int) String() string { 196 val := i.U.String() 197 if i.IsNegative() { 198 return "-" + val 199 } 200 201 return val 202 } 203 204 // Add will add the passed in value to the base value 205 // i = i + a. 206 func (i *Int) Add(a *Int) *Int { 207 // Handle cases where we have a zero 208 if a.IsZero() { 209 return i 210 } 211 if i.IsZero() { 212 i.U.Set(a.U) 213 i.s = a.s 214 215 return i 216 } 217 218 // Handle the easy cases were both are the same sign 219 if i.IsPositive() && a.IsPositive() { 220 i.U.Add(i.U, a.U) 221 222 return i 223 } 224 225 if i.IsNegative() && a.IsNegative() { 226 i.U.Add(i.U, a.U) 227 return i 228 } 229 230 // Now the cases where the signs are different 231 if i.IsNegative() { 232 if i.U.GTE(a.U) { 233 // abs(i) >= a 234 i.U.Sub(i.U, a.U) 235 } else { 236 // abs(i) < a 237 i.U.Sub(a.U, i.U) 238 i.s = true 239 } 240 241 return i 242 } 243 if i.U.GTE(a.U) { 244 // i >= abs(a) 245 i.U.Sub(i.U, a.U) 246 } else { 247 // i < abs(a) 248 i.U.Sub(a.U, i.U) 249 i.s = false 250 } 251 252 return i 253 } 254 255 // Sub will subtract the passed in value from the base value 256 // i = i - a. 257 func (i *Int) Sub(a *Int) *Int { 258 a.FlipSign() 259 i.Add(a) 260 a.FlipSign() 261 262 return i 263 } 264 265 // AddSum adds all of the parameters to i 266 // i = i + a + b + c. 267 func (i *Int) AddSum(vals ...*Int) *Int { 268 for _, x := range vals { 269 i.Add(x) 270 } 271 272 return i 273 } 274 275 // SubSum subtracts all of the parameters from i 276 // i = i - a - b - c. 277 func (i *Int) SubSum(vals ...*Int) *Int { 278 for _, x := range vals { 279 i.Sub(x) 280 } 281 282 return i 283 } 284 285 // Mul will multiply the passed in value to the base value 286 // i = i * m. 287 func (i *Int) Mul(m *Int) *Int { 288 i.U.Mul(i.U, m.U) 289 i.s = i.s == m.s 290 return i 291 } 292 293 // Mul will divide the passed in value to the base value 294 // i = i / m. 295 func (i *Int) Div(m *Int) *Int { 296 i.U.Div(i.U, m.U) 297 i.s = i.s == m.s 298 return i 299 } 300 301 // Value returns the string representation for SQL queries. 302 func (i *Int) Value() (driver.Value, error) { 303 str := i.String() 304 return str, nil 305 } 306 307 // Scan lets Uint.Scan do the heavy lifting, we just check for leading sign characters here. 308 func (i *Int) Scan(v any) error { 309 var str string 310 switch vt := v.(type) { 311 case string: 312 str = vt 313 case []byte: 314 str = string(vt) 315 default: 316 return ErrInvalidScanInput 317 } 318 i.s = true 319 // set sign flag, strip leading +/- sign. 320 switch str[0:1] { 321 case "-": 322 i.s = false 323 fallthrough 324 case "+": 325 str = str[1:] 326 } 327 return i.U.Scan(str) 328 } 329 330 // NewInt creates a new Int with the value of the 331 // int64 passed as a parameter. 332 func NewInt(val int64) *Int { 333 if val < 0 { 334 return &Int{ 335 U: NewUint(uint64(-val)), 336 s: false, 337 } 338 } 339 340 return &Int{ 341 U: NewUint(uint64(val)), 342 s: true, 343 } 344 } 345 346 func IntZero() *Int { 347 return intZero.Clone() 348 } 349 350 // NewIntFromUint creates a new Int with the value of the 351 // uint passed as a parameter. 352 func NewIntFromUint(val *Uint) *Int { 353 return &Int{ 354 U: val, 355 s: true, 356 } 357 }