(五) solidity的位运算实践

(五) solidity的位运算实践

viEcho Lv5

✅代码

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{
// x = 1110 = 8 + 4 + 2 + 0 = 14
// y = 1011 = 8 + 0 + 2 + 1 = 11
// x & y = 1010 = 8 + 0 + 2 + 0 = 10
// 与 -> 同1为1 不同为0
function and(uint256 x, uint256 y) external pure returns (uint256) {
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
// 或 -> 同1为1 同0为0 不同为1
function or(uint256 x, uint256 y) external pure returns (uint256) {
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
// 异或 -> 同1为0 同0为0 不同为1
function xor(uint256 x,uint256 y) external pure returns (uint256) {
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
// 取反 -> 取反 0 to 1,1 to 0
function not(uint256 x) external pure returns (uint256) {
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(uint256 x,uint256 bits) external pure returns (uint256) {
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(uint256 x,uint256 bits) external pure returns(uint256){
return x >> bits;
}

// get last n bits from x
// example, 13 last 3 bits
// x = 1101 = 13
// mask = (1<<n)-1
// 0001 << 3 = 1000 - 1 = 0111 = 6
// output = 1101 & 0111 = 0101 = 4 + 1 = 5

// example, 8 last 2 bits
// x = 0100 = 8
// mask = (1<<2)-1
// 0001 << 2 = 0100 - 1 = 0011 = 3
// output = 0100 & 0011 = 0000 = 0
function getLastNBits(uint256 x,uint256 n)external pure returns(uint256){
uint mask = (1<<n) - 1;
return x & mask;
}
//- 数学上, x % (1 << n) 等价于 x & ((1 << n) - 1)
//- 但模运算方法少了一次减法操作(不需要 -1 )
function getLastNBitUsingMod(uint256 x,uint n) external pure returns(uint256){
return x % (1<<n);
}
}

📚位与、位或,异或、取反

位与:同1为1,不同为0

  • 掩码操作(提取特定位)
  • 清零某些位

位或:只要有一个为1则为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; // 0001 (1)
uint LOCKED = 1 << 1; // 0010 (2)
uint VIP = 1 << 2; // 0100 (4)
uint VVIP = 1 << 3; // 1000 (8)
uint SVIP = 1 << 4; // 10000 (16)
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;
}
}
  • Title: (五) solidity的位运算实践
  • Author: viEcho
  • Created at : 2025-05-11 15:46:04
  • Updated at : 2025-05-11 16:32:28
  • Link: https://viecho.github.io/2025/0511/solidity-wei-math.html
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
(五) solidity的位运算实践