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 )