✅代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| contract BitwiseOps{ function and(uint256 x, uint256 y) external pure returns (uint256) { return x & y; } function or(uint256 x, uint256 y) external pure returns (uint256) { return x | y; } function xor(uint256 x,uint256 y) external pure returns (uint256) { return x ^ y; }
function not(uint256 x) external pure returns (uint256) { return ~x; }
function shiftLeft(uint256 x,uint256 bits) external pure returns (uint256) { return x << bits; } function shiftRight(uint256 x,uint256 bits) external pure returns(uint256){ return x >> bits; }
function getLastNBits(uint256 x,uint256 n)external pure returns(uint256){ uint mask = (1<<n) - 1; return x & mask; } function getLastNBitUsingMod(uint256 x,uint n) external pure returns(uint256){ return x % (1<<n); } }
|
📚位与、位或,异或、取反
位与:同1为1,不同为0
位或:只要有一个为1则为1
异或:只要不同就位1
- 任何数异或自己得0:x ^ x = 0
- 可逆性:x ^ y ^ y = x
- 交换两个变量的值
- 简单加密/解密
- 校验数据
取反:0为1,1为0
📚位移
左移:x << n,二进制的表现形式为所有位向左移动n位;对于数学上的表现形式为:x乘以2的n次方
右移:x >> n,二进制的表现形式为所有位向右移动n位; 对于数学上的表现形式为:x除以2的n次方
- 常用于数据结构的扩容 或者使用一个标志位记录某个状态的值
以下是一个简单的状态标志位的实现(java代码类似):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| contract Example{ uint ACTIVE = 1 << 0; uint LOCKED = 1 << 1; uint VIP = 1 << 2; uint VVIP = 1 << 3; uint SVIP = 1 << 4; uint ALL = ACTIVE | LOCKED | VIP | VVIP | SVIP;
function setStatus(uint _status) external { require(status <= ALL, "Invalid status"); status |= _status; } function unsetStatus(uint _status) external { status &= ~_status; } function hashStatus(uint _status) external view returns(uint) { return (status & _status) == _status; } }
|