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