mirror of
https://github.com/autistic-symposium/web3-starter-sol.git
synced 2025-07-21 14:18:51 -04:00
200 lines
4.9 KiB
Markdown
200 lines
4.9 KiB
Markdown
## bitwise operators
|
|
|
|
<br>
|
|
|
|
### example of bitwise operations
|
|
|
|
```
|
|
contract BitwiseOps {
|
|
// x = 1110 = 8 + 4 + 2 + 0 = 14
|
|
// y = 1011 = 8 + 0 + 2 + 1 = 11
|
|
// x & y = 1010 = 8 + 0 + 2 + 0 = 10
|
|
function and(uint x, uint y) external pure returns (uint) {
|
|
return x & y;
|
|
}
|
|
|
|
// x = 1100 = 8 + 4 + 0 + 0 = 12
|
|
// y = 1001 = 8 + 0 + 0 + 1 = 9
|
|
// x | y = 1101 = 8 + 4 + 0 + 1 = 13
|
|
function or(uint x, uint y) external pure returns (uint) {
|
|
return x | y;
|
|
}
|
|
|
|
// x = 1100 = 8 + 4 + 0 + 0 = 12
|
|
// y = 0101 = 0 + 4 + 0 + 1 = 5
|
|
// x ^ y = 1001 = 8 + 0 + 0 + 1 = 9
|
|
function xor(uint x, uint y) external pure returns (uint) {
|
|
return x ^ y;
|
|
}
|
|
|
|
// x = 00001100 = 0 + 0 + 0 + 0 + 8 + 4 + 0 + 0 = 12
|
|
// ~x = 11110011 = 128 + 64 + 32 + 16 + 0 + 0 + 2 + 1 = 243
|
|
function not(uint8 x) external pure returns (uint8) {
|
|
return ~x;
|
|
}
|
|
|
|
// 1 << 0 = 0001 --> 0001 = 1
|
|
// 1 << 1 = 0001 --> 0010 = 2
|
|
// 1 << 2 = 0001 --> 0100 = 4
|
|
// 1 << 3 = 0001 --> 1000 = 8
|
|
// 3 << 2 = 0011 --> 1100 = 12
|
|
function shiftLeft(uint x, uint bits) external pure returns (uint) {
|
|
return x << bits;
|
|
}
|
|
|
|
// 8 >> 0 = 1000 --> 1000 = 8
|
|
// 8 >> 1 = 1000 --> 0100 = 4
|
|
// 8 >> 2 = 1000 --> 0010 = 2
|
|
// 8 >> 3 = 1000 --> 0001 = 1
|
|
// 8 >> 4 = 1000 --> 0000 = 0
|
|
// 12 >> 1 = 1100 --> 0110 = 6
|
|
function shiftRight(uint x, uint bits) external pure returns (uint) {
|
|
return x >> bits;
|
|
}
|
|
|
|
// Get last n bits from x
|
|
function getLastNBits(uint x, uint n) external pure returns (uint) {
|
|
// Example, last 3 bits
|
|
// x = 1101 = 13
|
|
// mask = 0111 = 7
|
|
// x & mask = 0101 = 5
|
|
uint mask = (1 << n) - 1;
|
|
return x & mask;
|
|
}
|
|
|
|
// Get last n bits from x using mod operator
|
|
function getLastNBitsUsingMod(uint x, uint n) external pure returns (uint) {
|
|
// 1 << n = 2 ** n
|
|
return x % (1 << n);
|
|
}
|
|
|
|
// Get position of most significant bit
|
|
// x = 1100 = 10, most significant bit = 1000, so this function will return 3
|
|
function mostSignificantBit(uint x) external pure returns (uint) {
|
|
uint i = 0;
|
|
while ((x >>= 1) > 0) {
|
|
++i;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
// Get first n bits from x
|
|
// len = length of bits in x = position of most significant bit of x, + 1
|
|
function getFirstNBits(uint x, uint n, uint len) external pure returns (uint) {
|
|
// Example
|
|
// x = 1110 = 14, n = 2, len = 4
|
|
// mask = 1100 = 12
|
|
// x & mask = 1100 = 12
|
|
uint mask = ((1 << n) - 1) << (len - n);
|
|
return x & mask;
|
|
}
|
|
}
|
|
```
|
|
|
|
<br>
|
|
|
|
----
|
|
|
|
### most significant bit
|
|
|
|
<br>
|
|
|
|
```
|
|
contract MostSignificantBitFunction {
|
|
// Find most significant bit using binary search
|
|
function mostSignificantBit(uint x) external pure returns (uint msb) {
|
|
// x >= 2 ** 128
|
|
if (x >= 0x100000000000000000000000000000000) {
|
|
x >>= 128;
|
|
msb += 128;
|
|
}
|
|
// x >= 2 ** 64
|
|
if (x >= 0x10000000000000000) {
|
|
x >>= 64;
|
|
msb += 64;
|
|
}
|
|
// x >= 2 ** 32
|
|
if (x >= 0x100000000) {
|
|
x >>= 32;
|
|
msb += 32;
|
|
}
|
|
// x >= 2 ** 16
|
|
if (x >= 0x10000) {
|
|
x >>= 16;
|
|
msb += 16;
|
|
}
|
|
// x >= 2 ** 8
|
|
if (x >= 0x100) {
|
|
x >>= 8;
|
|
msb += 8;
|
|
}
|
|
// x >= 2 ** 4
|
|
if (x >= 0x10) {
|
|
x >>= 4;
|
|
msb += 4;
|
|
}
|
|
// x >= 2 ** 2
|
|
if (x >= 0x4) {
|
|
x >>= 2;
|
|
msb += 2;
|
|
}
|
|
// x >= 2 ** 1
|
|
if (x >= 0x2) msb += 1;
|
|
}
|
|
}
|
|
```
|
|
|
|
<br>
|
|
|
|
----
|
|
|
|
### most significant bit in assembly
|
|
|
|
<br>
|
|
|
|
```
|
|
contract MostSignificantBitAssembly {
|
|
function mostSignificantBit(uint x) external pure returns (uint msb) {
|
|
assembly {
|
|
let f := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
|
|
x := shr(f, x)
|
|
// or can be replaced with add
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(5, gt(x, 0xFFFFFFFF))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(4, gt(x, 0xFFFF))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(3, gt(x, 0xFF))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(2, gt(x, 0xF))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := shl(1, gt(x, 0x3))
|
|
x := shr(f, x)
|
|
msb := or(msb, f)
|
|
}
|
|
assembly {
|
|
let f := gt(x, 0x1)
|
|
msb := or(msb, f)
|
|
}
|
|
}
|
|
}
|
|
```
|