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  }