github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/uint256/bitwise.gno (about) 1 // bitwise contains bitwise operations for Uint instances. 2 // This file includes functions to perform bitwise AND, OR, XOR, and NOT operations, as well as bit shifting. 3 // These operations are crucial for manipulating individual bits within a 256-bit unsigned integer. 4 package uint256 5 6 // Or sets z = x | y and returns z. 7 func (z *Uint) Or(x, y *Uint) *Uint { 8 z.arr[0] = x.arr[0] | y.arr[0] 9 z.arr[1] = x.arr[1] | y.arr[1] 10 z.arr[2] = x.arr[2] | y.arr[2] 11 z.arr[3] = x.arr[3] | y.arr[3] 12 return z 13 } 14 15 // And sets z = x & y and returns z. 16 func (z *Uint) And(x, y *Uint) *Uint { 17 z.arr[0] = x.arr[0] & y.arr[0] 18 z.arr[1] = x.arr[1] & y.arr[1] 19 z.arr[2] = x.arr[2] & y.arr[2] 20 z.arr[3] = x.arr[3] & y.arr[3] 21 return z 22 } 23 24 // Not sets z = ^x and returns z. 25 func (z *Uint) Not(x *Uint) *Uint { 26 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = ^x.arr[3], ^x.arr[2], ^x.arr[1], ^x.arr[0] 27 return z 28 } 29 30 // AndNot sets z = x &^ y and returns z. 31 func (z *Uint) AndNot(x, y *Uint) *Uint { 32 z.arr[0] = x.arr[0] &^ y.arr[0] 33 z.arr[1] = x.arr[1] &^ y.arr[1] 34 z.arr[2] = x.arr[2] &^ y.arr[2] 35 z.arr[3] = x.arr[3] &^ y.arr[3] 36 return z 37 } 38 39 // Xor sets z = x ^ y and returns z. 40 func (z *Uint) Xor(x, y *Uint) *Uint { 41 z.arr[0] = x.arr[0] ^ y.arr[0] 42 z.arr[1] = x.arr[1] ^ y.arr[1] 43 z.arr[2] = x.arr[2] ^ y.arr[2] 44 z.arr[3] = x.arr[3] ^ y.arr[3] 45 return z 46 } 47 48 // Lsh sets z = x << n and returns z. 49 func (z *Uint) Lsh(x *Uint, n uint) *Uint { 50 // n % 64 == 0 51 if n&0x3f == 0 { 52 switch n { 53 case 0: 54 return z.Set(x) 55 case 64: 56 return z.lsh64(x) 57 case 128: 58 return z.lsh128(x) 59 case 192: 60 return z.lsh192(x) 61 default: 62 return z.Clear() 63 } 64 } 65 var a, b uint64 66 // Big swaps first 67 switch { 68 case n > 192: 69 if n > 256 { 70 return z.Clear() 71 } 72 z.lsh192(x) 73 n -= 192 74 goto sh192 75 case n > 128: 76 z.lsh128(x) 77 n -= 128 78 goto sh128 79 case n > 64: 80 z.lsh64(x) 81 n -= 64 82 goto sh64 83 default: 84 z.Set(x) 85 } 86 87 // remaining shifts 88 a = z.arr[0] >> (64 - n) 89 z.arr[0] = z.arr[0] << n 90 91 sh64: 92 b = z.arr[1] >> (64 - n) 93 z.arr[1] = (z.arr[1] << n) | a 94 95 sh128: 96 a = z.arr[2] >> (64 - n) 97 z.arr[2] = (z.arr[2] << n) | b 98 99 sh192: 100 z.arr[3] = (z.arr[3] << n) | a 101 102 return z 103 } 104 105 // Rsh sets z = x >> n and returns z. 106 func (z *Uint) Rsh(x *Uint, n uint) *Uint { 107 // n % 64 == 0 108 if n&0x3f == 0 { 109 switch n { 110 case 0: 111 return z.Set(x) 112 case 64: 113 return z.rsh64(x) 114 case 128: 115 return z.rsh128(x) 116 case 192: 117 return z.rsh192(x) 118 default: 119 return z.Clear() 120 } 121 } 122 var a, b uint64 123 // Big swaps first 124 switch { 125 case n > 192: 126 if n > 256 { 127 return z.Clear() 128 } 129 z.rsh192(x) 130 n -= 192 131 goto sh192 132 case n > 128: 133 z.rsh128(x) 134 n -= 128 135 goto sh128 136 case n > 64: 137 z.rsh64(x) 138 n -= 64 139 goto sh64 140 default: 141 z.Set(x) 142 } 143 144 // remaining shifts 145 a = z.arr[3] << (64 - n) 146 z.arr[3] = z.arr[3] >> n 147 148 sh64: 149 b = z.arr[2] << (64 - n) 150 z.arr[2] = (z.arr[2] >> n) | a 151 152 sh128: 153 a = z.arr[1] << (64 - n) 154 z.arr[1] = (z.arr[1] >> n) | b 155 156 sh192: 157 z.arr[0] = (z.arr[0] >> n) | a 158 159 return z 160 } 161 162 // SRsh (Signed/Arithmetic right shift) 163 // considers z to be a signed integer, during right-shift 164 // and sets z = x >> n and returns z. 165 func (z *Uint) SRsh(x *Uint, n uint) *Uint { 166 // If the MSB is 0, SRsh is same as Rsh. 167 if !x.isBitSet(255) { 168 return z.Rsh(x, n) 169 } 170 if n%64 == 0 { 171 switch n { 172 case 0: 173 return z.Set(x) 174 case 64: 175 return z.srsh64(x) 176 case 128: 177 return z.srsh128(x) 178 case 192: 179 return z.srsh192(x) 180 default: 181 return z.SetAllOne() 182 } 183 } 184 var a uint64 = MaxUint64 << (64 - n%64) 185 // Big swaps first 186 switch { 187 case n > 192: 188 if n > 256 { 189 return z.SetAllOne() 190 } 191 z.srsh192(x) 192 n -= 192 193 goto sh192 194 case n > 128: 195 z.srsh128(x) 196 n -= 128 197 goto sh128 198 case n > 64: 199 z.srsh64(x) 200 n -= 64 201 goto sh64 202 default: 203 z.Set(x) 204 } 205 206 // remaining shifts 207 z.arr[3], a = (z.arr[3]>>n)|a, z.arr[3]<<(64-n) 208 209 sh64: 210 z.arr[2], a = (z.arr[2]>>n)|a, z.arr[2]<<(64-n) 211 212 sh128: 213 z.arr[1], a = (z.arr[1]>>n)|a, z.arr[1]<<(64-n) 214 215 sh192: 216 z.arr[0] = (z.arr[0] >> n) | a 217 218 return z 219 } 220 221 func (z *Uint) lsh64(x *Uint) *Uint { 222 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = x.arr[2], x.arr[1], x.arr[0], 0 223 return z 224 } 225 226 func (z *Uint) lsh128(x *Uint) *Uint { 227 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = x.arr[1], x.arr[0], 0, 0 228 return z 229 } 230 231 func (z *Uint) lsh192(x *Uint) *Uint { 232 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = x.arr[0], 0, 0, 0 233 return z 234 } 235 236 func (z *Uint) rsh64(x *Uint) *Uint { 237 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, x.arr[3], x.arr[2], x.arr[1] 238 return z 239 } 240 241 func (z *Uint) rsh128(x *Uint) *Uint { 242 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, x.arr[3], x.arr[2] 243 return z 244 } 245 246 func (z *Uint) rsh192(x *Uint) *Uint { 247 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, 0, x.arr[3] 248 return z 249 } 250 251 func (z *Uint) srsh64(x *Uint) *Uint { 252 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = MaxUint64, x.arr[3], x.arr[2], x.arr[1] 253 return z 254 } 255 256 func (z *Uint) srsh128(x *Uint) *Uint { 257 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = MaxUint64, MaxUint64, x.arr[3], x.arr[2] 258 return z 259 } 260 261 func (z *Uint) srsh192(x *Uint) *Uint { 262 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = MaxUint64, MaxUint64, MaxUint64, x.arr[3] 263 return z 264 }