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