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  }