github.com/Finschia/finschia-sdk@v0.48.1/types/int.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding"
     5  	"encoding/json"
     6  	"fmt"
     7  	"math/big"
     8  	"testing"
     9  )
    10  
    11  const maxBitLen = 256
    12  
    13  func newIntegerFromString(s string) (*big.Int, bool) {
    14  	return new(big.Int).SetString(s, 0)
    15  }
    16  
    17  func equal(i *big.Int, i2 *big.Int) bool { return i.Cmp(i2) == 0 }
    18  
    19  func gt(i *big.Int, i2 *big.Int) bool { return i.Cmp(i2) == 1 }
    20  
    21  func gte(i *big.Int, i2 *big.Int) bool { return i.Cmp(i2) >= 0 }
    22  
    23  func lt(i *big.Int, i2 *big.Int) bool { return i.Cmp(i2) == -1 }
    24  
    25  func lte(i *big.Int, i2 *big.Int) bool { return i.Cmp(i2) <= 0 }
    26  
    27  func add(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Add(i, i2) }
    28  
    29  func sub(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Sub(i, i2) }
    30  
    31  func mul(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Mul(i, i2) }
    32  
    33  func div(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Quo(i, i2) }
    34  
    35  func mod(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Mod(i, i2) }
    36  
    37  func neg(i *big.Int) *big.Int { return new(big.Int).Neg(i) }
    38  
    39  func abs(i *big.Int) *big.Int { return new(big.Int).Abs(i) }
    40  
    41  func min(i *big.Int, i2 *big.Int) *big.Int {
    42  	if i.Cmp(i2) == 1 {
    43  		return new(big.Int).Set(i2)
    44  	}
    45  
    46  	return new(big.Int).Set(i)
    47  }
    48  
    49  func max(i *big.Int, i2 *big.Int) *big.Int {
    50  	if i.Cmp(i2) == -1 {
    51  		return new(big.Int).Set(i2)
    52  	}
    53  
    54  	return new(big.Int).Set(i)
    55  }
    56  
    57  func unmarshalText(i *big.Int, text string) error {
    58  	if err := i.UnmarshalText([]byte(text)); err != nil {
    59  		return err
    60  	}
    61  
    62  	if i.BitLen() > maxBitLen {
    63  		return fmt.Errorf("integer out of range: %s", text)
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  var _ CustomProtobufType = (*Int)(nil)
    70  
    71  // Int wraps big.Int with a 257 bit range bound
    72  // Checks overflow, underflow and division by zero
    73  // Exists in range from -(2^256 - 1) to 2^256 - 1
    74  type Int struct {
    75  	i *big.Int
    76  }
    77  
    78  // BigInt converts Int to big.Int
    79  func (i Int) BigInt() *big.Int {
    80  	if i.IsNil() {
    81  		return nil
    82  	}
    83  	return new(big.Int).Set(i.i)
    84  }
    85  
    86  // IsNil returns true if Int is uninitialized
    87  func (i Int) IsNil() bool {
    88  	return i.i == nil
    89  }
    90  
    91  // NewInt constructs Int from int64
    92  func NewInt(n int64) Int {
    93  	return Int{big.NewInt(n)}
    94  }
    95  
    96  // NewIntFromUint64 constructs an Int from a uint64.
    97  func NewIntFromUint64(n uint64) Int {
    98  	b := big.NewInt(0)
    99  	b.SetUint64(n)
   100  	return Int{b}
   101  }
   102  
   103  // NewIntFromBigInt constructs Int from big.Int. If the provided big.Int is nil,
   104  // it returns an empty instance. This function panics if the bit length is > 256.
   105  func NewIntFromBigInt(i *big.Int) Int {
   106  	if i == nil {
   107  		return Int{}
   108  	}
   109  
   110  	if i.BitLen() > maxBitLen {
   111  		panic("NewIntFromBigInt() out of bound")
   112  	}
   113  	return Int{i}
   114  }
   115  
   116  // NewIntFromString constructs Int from string
   117  func NewIntFromString(s string) (res Int, ok bool) {
   118  	i, ok := newIntegerFromString(s)
   119  	if !ok {
   120  		return
   121  	}
   122  	// Check overflow
   123  	if i.BitLen() > maxBitLen {
   124  		ok = false
   125  		return
   126  	}
   127  	return Int{i}, true
   128  }
   129  
   130  // NewIntWithDecimal constructs Int with decimal
   131  // Result value is n*10^dec
   132  func NewIntWithDecimal(n int64, dec int) Int {
   133  	if dec < 0 {
   134  		panic("NewIntWithDecimal() decimal is negative")
   135  	}
   136  	exp := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(dec)), nil)
   137  	i := new(big.Int)
   138  	i.Mul(big.NewInt(n), exp)
   139  
   140  	// Check overflow
   141  	if i.BitLen() > maxBitLen {
   142  		panic("NewIntWithDecimal() out of bound")
   143  	}
   144  	return Int{i}
   145  }
   146  
   147  // ZeroInt returns Int value with zero
   148  func ZeroInt() Int { return Int{big.NewInt(0)} }
   149  
   150  // OneInt returns Int value with one
   151  func OneInt() Int { return Int{big.NewInt(1)} }
   152  
   153  // ToDec converts Int to Dec
   154  func (i Int) ToDec() Dec {
   155  	return NewDecFromInt(i)
   156  }
   157  
   158  // Int64 converts Int to int64
   159  // Panics if the value is out of range
   160  func (i Int) Int64() int64 {
   161  	if !i.i.IsInt64() {
   162  		panic("Int64() out of bound")
   163  	}
   164  	return i.i.Int64()
   165  }
   166  
   167  // IsInt64 returns true if Int64() not panics
   168  func (i Int) IsInt64() bool {
   169  	return i.i.IsInt64()
   170  }
   171  
   172  // Uint64 converts Int to uint64
   173  // Panics if the value is out of range
   174  func (i Int) Uint64() uint64 {
   175  	if !i.i.IsUint64() {
   176  		panic("Uint64() out of bounds")
   177  	}
   178  	return i.i.Uint64()
   179  }
   180  
   181  // IsUint64 returns true if Uint64() not panics
   182  func (i Int) IsUint64() bool {
   183  	return i.i.IsUint64()
   184  }
   185  
   186  // IsZero returns true if Int is zero
   187  func (i Int) IsZero() bool {
   188  	return i.i.Sign() == 0
   189  }
   190  
   191  // IsNegative returns true if Int is negative
   192  func (i Int) IsNegative() bool {
   193  	return i.i.Sign() == -1
   194  }
   195  
   196  // IsPositive returns true if Int is positive
   197  func (i Int) IsPositive() bool {
   198  	return i.i.Sign() == 1
   199  }
   200  
   201  // Sign returns sign of Int
   202  func (i Int) Sign() int {
   203  	return i.i.Sign()
   204  }
   205  
   206  // Equal compares two Ints
   207  func (i Int) Equal(i2 Int) bool {
   208  	return equal(i.i, i2.i)
   209  }
   210  
   211  // GT returns true if first Int is greater than second
   212  func (i Int) GT(i2 Int) bool {
   213  	return gt(i.i, i2.i)
   214  }
   215  
   216  // GTE returns true if receiver Int is greater than or equal to the parameter
   217  // Int.
   218  func (i Int) GTE(i2 Int) bool {
   219  	return gte(i.i, i2.i)
   220  }
   221  
   222  // LT returns true if first Int is lesser than second
   223  func (i Int) LT(i2 Int) bool {
   224  	return lt(i.i, i2.i)
   225  }
   226  
   227  // LTE returns true if first Int is less than or equal to second
   228  func (i Int) LTE(i2 Int) bool {
   229  	return lte(i.i, i2.i)
   230  }
   231  
   232  // Add adds Int from another
   233  func (i Int) Add(i2 Int) (res Int) {
   234  	res = Int{add(i.i, i2.i)}
   235  	// Check overflow
   236  	if res.i.BitLen() > maxBitLen {
   237  		panic("Int overflow")
   238  	}
   239  	return
   240  }
   241  
   242  // AddRaw adds int64 to Int
   243  func (i Int) AddRaw(i2 int64) Int {
   244  	return i.Add(NewInt(i2))
   245  }
   246  
   247  // Sub subtracts Int from another
   248  func (i Int) Sub(i2 Int) (res Int) {
   249  	res = Int{sub(i.i, i2.i)}
   250  	// Check overflow
   251  	if res.i.BitLen() > maxBitLen {
   252  		panic("Int overflow")
   253  	}
   254  	return
   255  }
   256  
   257  // SubRaw subtracts int64 from Int
   258  func (i Int) SubRaw(i2 int64) Int {
   259  	return i.Sub(NewInt(i2))
   260  }
   261  
   262  // Mul multiples two Ints
   263  func (i Int) Mul(i2 Int) (res Int) {
   264  	// Check overflow
   265  	if i.i.BitLen()+i2.i.BitLen()-1 > maxBitLen {
   266  		panic("Int overflow")
   267  	}
   268  	res = Int{mul(i.i, i2.i)}
   269  	// Check overflow if sign of both are same
   270  	if res.i.BitLen() > maxBitLen {
   271  		panic("Int overflow")
   272  	}
   273  	return
   274  }
   275  
   276  // MulRaw multipies Int and int64
   277  func (i Int) MulRaw(i2 int64) Int {
   278  	return i.Mul(NewInt(i2))
   279  }
   280  
   281  // Quo divides Int with Int
   282  func (i Int) Quo(i2 Int) (res Int) {
   283  	// Check division-by-zero
   284  	if i2.i.Sign() == 0 {
   285  		panic("Division by zero")
   286  	}
   287  	return Int{div(i.i, i2.i)}
   288  }
   289  
   290  // QuoRaw divides Int with int64
   291  func (i Int) QuoRaw(i2 int64) Int {
   292  	return i.Quo(NewInt(i2))
   293  }
   294  
   295  // Mod returns remainder after dividing with Int
   296  func (i Int) Mod(i2 Int) Int {
   297  	if i2.Sign() == 0 {
   298  		panic("division-by-zero")
   299  	}
   300  	return Int{mod(i.i, i2.i)}
   301  }
   302  
   303  // ModRaw returns remainder after dividing with int64
   304  func (i Int) ModRaw(i2 int64) Int {
   305  	return i.Mod(NewInt(i2))
   306  }
   307  
   308  // Neg negates Int
   309  func (i Int) Neg() (res Int) {
   310  	return Int{neg(i.i)}
   311  }
   312  
   313  // Abs returns the absolute value of Int.
   314  func (i Int) Abs() Int {
   315  	return Int{abs(i.i)}
   316  }
   317  
   318  // return the minimum of the ints
   319  func MinInt(i1, i2 Int) Int {
   320  	return Int{min(i1.BigInt(), i2.BigInt())}
   321  }
   322  
   323  // MaxInt returns the maximum between two integers.
   324  func MaxInt(i, i2 Int) Int {
   325  	return Int{max(i.BigInt(), i2.BigInt())}
   326  }
   327  
   328  // Human readable string
   329  func (i Int) String() string {
   330  	return i.i.String()
   331  }
   332  
   333  // MarshalJSON defines custom encoding scheme
   334  func (i Int) MarshalJSON() ([]byte, error) {
   335  	if i.i == nil { // Necessary since default Uint initialization has i.i as nil
   336  		i.i = new(big.Int)
   337  	}
   338  	return marshalJSON(i.i)
   339  }
   340  
   341  // UnmarshalJSON defines custom decoding scheme
   342  func (i *Int) UnmarshalJSON(bz []byte) error {
   343  	if i.i == nil { // Necessary since default Int initialization has i.i as nil
   344  		i.i = new(big.Int)
   345  	}
   346  	return unmarshalJSON(i.i, bz)
   347  }
   348  
   349  // MarshalJSON for custom encoding scheme
   350  // Must be encoded as a string for JSON precision
   351  func marshalJSON(i encoding.TextMarshaler) ([]byte, error) {
   352  	text, err := i.MarshalText()
   353  	if err != nil {
   354  		return nil, err
   355  	}
   356  
   357  	return json.Marshal(string(text))
   358  }
   359  
   360  // UnmarshalJSON for custom decoding scheme
   361  // Must be encoded as a string for JSON precision
   362  func unmarshalJSON(i *big.Int, bz []byte) error {
   363  	var text string
   364  	if err := json.Unmarshal(bz, &text); err != nil {
   365  		return err
   366  	}
   367  
   368  	return unmarshalText(i, text)
   369  }
   370  
   371  // MarshalYAML returns the YAML representation.
   372  func (i Int) MarshalYAML() (interface{}, error) {
   373  	return i.String(), nil
   374  }
   375  
   376  // Marshal implements the gogo proto custom type interface.
   377  func (i Int) Marshal() ([]byte, error) {
   378  	if i.i == nil {
   379  		i.i = new(big.Int)
   380  	}
   381  	return i.i.MarshalText()
   382  }
   383  
   384  // MarshalTo implements the gogo proto custom type interface.
   385  func (i *Int) MarshalTo(data []byte) (n int, err error) {
   386  	if i.i == nil {
   387  		i.i = new(big.Int)
   388  	}
   389  	if i.i.BitLen() == 0 { // The value 0
   390  		copy(data, []byte{0x30})
   391  		return 1, nil
   392  	}
   393  
   394  	bz, err := i.Marshal()
   395  	if err != nil {
   396  		return 0, err
   397  	}
   398  
   399  	copy(data, bz)
   400  	return len(bz), nil
   401  }
   402  
   403  // Unmarshal implements the gogo proto custom type interface.
   404  func (i *Int) Unmarshal(data []byte) error {
   405  	if len(data) == 0 {
   406  		i = nil
   407  		return nil
   408  	}
   409  
   410  	if i.i == nil {
   411  		i.i = new(big.Int)
   412  	}
   413  
   414  	if err := i.i.UnmarshalText(data); err != nil {
   415  		return err
   416  	}
   417  
   418  	if i.i.BitLen() > maxBitLen {
   419  		return fmt.Errorf("integer out of range; got: %d, max: %d", i.i.BitLen(), maxBitLen)
   420  	}
   421  
   422  	return nil
   423  }
   424  
   425  // Size implements the gogo proto custom type interface.
   426  func (i *Int) Size() int {
   427  	bz, _ := i.Marshal()
   428  	return len(bz)
   429  }
   430  
   431  // Override Amino binary serialization by proxying to protobuf.
   432  func (i Int) MarshalAmino() ([]byte, error)   { return i.Marshal() }
   433  func (i *Int) UnmarshalAmino(bz []byte) error { return i.Unmarshal(bz) }
   434  
   435  // intended to be used with require/assert:  require.True(IntEq(...))
   436  func IntEq(t *testing.T, exp, got Int) (*testing.T, bool, string, string, string) {
   437  	return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String()
   438  }
   439  
   440  func (ip IntProto) String() string {
   441  	return ip.Int.String()
   442  }