github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/common/number/int.go (about)

     1  // Copyright 2015 The Spectrum Authors
     2  // This file is part of the Spectrum library.
     3  //
     4  // The Spectrum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The Spectrum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the Spectrum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package number
    18  
    19  import (
    20  	"math/big"
    21  
    22  	"github.com/SmartMeshFoundation/Spectrum/common"
    23  )
    24  
    25  var tt256 = new(big.Int).Lsh(big.NewInt(1), 256)
    26  var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))
    27  var tt255 = new(big.Int).Lsh(big.NewInt(1), 255)
    28  
    29  func limitUnsigned256(x *Number) *Number {
    30  	x.num.And(x.num, tt256m1)
    31  	return x
    32  }
    33  
    34  func limitSigned256(x *Number) *Number {
    35  	if x.num.Cmp(tt255) < 0 {
    36  		return x
    37  	} else {
    38  		x.num.Sub(x.num, tt256)
    39  		return x
    40  	}
    41  }
    42  
    43  // Number function
    44  type Initialiser func(n int64) *Number
    45  
    46  // A Number represents a generic integer with a bounding function limiter. Limit is called after each operations
    47  // to give "fake" bounded integers. New types of Number can be created through NewInitialiser returning a lambda
    48  // with the new Initialiser.
    49  type Number struct {
    50  	num   *big.Int
    51  	limit func(n *Number) *Number
    52  }
    53  
    54  // Returns a new initialiser for a new *Number without having to expose certain fields
    55  func NewInitialiser(limiter func(*Number) *Number) Initialiser {
    56  	return func(n int64) *Number {
    57  		return &Number{big.NewInt(n), limiter}
    58  	}
    59  }
    60  
    61  // Return a Number with a UNSIGNED limiter up to 256 bits
    62  func Uint256(n int64) *Number {
    63  	return &Number{big.NewInt(n), limitUnsigned256}
    64  }
    65  
    66  // Return a Number with a UNSIGNED limiter up to 256 bits
    67  func BigToUint256(i *big.Int) *Number {
    68  	return &Number{i, limitUnsigned256}
    69  }
    70  
    71  // Return a Number with a SIGNED limiter up to 256 bits
    72  func Int256(n int64) *Number {
    73  	return &Number{big.NewInt(n), limitSigned256}
    74  }
    75  
    76  // Returns a Number with a SIGNED unlimited size
    77  func Big(n int64) *Number {
    78  	return &Number{big.NewInt(n), func(x *Number) *Number { return x }}
    79  }
    80  
    81  // Sets i to sum of x+y
    82  func (i *Number) Add(x, y *Number) *Number {
    83  	i.num.Add(x.num, y.num)
    84  	return i.limit(i)
    85  }
    86  
    87  // Sets i to difference of x-y
    88  func (i *Number) Sub(x, y *Number) *Number {
    89  	i.num.Sub(x.num, y.num)
    90  	return i.limit(i)
    91  }
    92  
    93  // Sets i to product of x*y
    94  func (i *Number) Mul(x, y *Number) *Number {
    95  	i.num.Mul(x.num, y.num)
    96  	return i.limit(i)
    97  }
    98  
    99  // Sets i to the quotient prodject of x/y
   100  func (i *Number) Div(x, y *Number) *Number {
   101  	i.num.Div(x.num, y.num)
   102  	return i.limit(i)
   103  }
   104  
   105  // Sets i to x % y
   106  func (i *Number) Mod(x, y *Number) *Number {
   107  	i.num.Mod(x.num, y.num)
   108  	return i.limit(i)
   109  }
   110  
   111  // Sets i to x << s
   112  func (i *Number) Lsh(x *Number, s uint) *Number {
   113  	i.num.Lsh(x.num, s)
   114  	return i.limit(i)
   115  }
   116  
   117  // Sets i to x^y
   118  func (i *Number) Pow(x, y *Number) *Number {
   119  	i.num.Exp(x.num, y.num, big.NewInt(0))
   120  	return i.limit(i)
   121  }
   122  
   123  // Setters
   124  
   125  // Set x to i
   126  func (i *Number) Set(x *Number) *Number {
   127  	i.num.Set(x.num)
   128  	return i.limit(i)
   129  }
   130  
   131  // Set x bytes to i
   132  func (i *Number) SetBytes(x []byte) *Number {
   133  	i.num.SetBytes(x)
   134  	return i.limit(i)
   135  }
   136  
   137  // Cmp compares x and y and returns:
   138  //
   139  //     -1 if x <  y
   140  //     0 if x == y
   141  //     +1 if x >  y
   142  func (i *Number) Cmp(x *Number) int {
   143  	return i.num.Cmp(x.num)
   144  }
   145  
   146  // Getters
   147  
   148  // Returns the string representation of i
   149  func (i *Number) String() string {
   150  	return i.num.String()
   151  }
   152  
   153  // Returns the byte representation of i
   154  func (i *Number) Bytes() []byte {
   155  	return i.num.Bytes()
   156  }
   157  
   158  // Uint64 returns the Uint64 representation of x. If x cannot be represented in an int64, the result is undefined.
   159  func (i *Number) Uint64() uint64 {
   160  	return i.num.Uint64()
   161  }
   162  
   163  // Int64 returns the int64 representation of x. If x cannot be represented in an int64, the result is undefined.
   164  func (i *Number) Int64() int64 {
   165  	return i.num.Int64()
   166  }
   167  
   168  // Returns the signed version of i
   169  func (i *Number) Int256() *Number {
   170  	return Int(0).Set(i)
   171  }
   172  
   173  // Returns the unsigned version of i
   174  func (i *Number) Uint256() *Number {
   175  	return Uint(0).Set(i)
   176  }
   177  
   178  // Returns the index of the first bit that's set to 1
   179  func (i *Number) FirstBitSet() int {
   180  	for j := 0; j < i.num.BitLen(); j++ {
   181  		if i.num.Bit(j) > 0 {
   182  			return j
   183  		}
   184  	}
   185  
   186  	return i.num.BitLen()
   187  }
   188  
   189  // Variables
   190  
   191  var (
   192  	Zero       = Uint(0)
   193  	One        = Uint(1)
   194  	Two        = Uint(2)
   195  	MaxUint256 = Uint(0).SetBytes(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"))
   196  
   197  	MinOne = Int(-1)
   198  
   199  	// "typedefs"
   200  	Uint = Uint256
   201  	Int  = Int256
   202  )