整数
int/ uint:各种大小的有符号和无符号整数。关键字uint8to uint256(8无符号 8 到 256 位)和int8to int256。uint和分别是和int的别名。uint256int256
运营商:
- 比较:<=, <, ==, !=, >=, >(计算为bool)
- 位运算符:&, |, ^(按位异或),~(按位否定)
- 移位运算符:(<<左移)、>>(右移)
- 算术运算符:+, -, 一元-(仅适用于有符号整数), *, /, %(模), **(幂)
对于整数类型X,您可以使用type(X).min和type(X).max访问该类型可表示的最小值和最大值。
警告
Solidity 中的整数被限制在一定范围内。例如,使用uint32,这0取决于。对这些类型执行算术运算有两种模式:“包装”或“未检查”模式和“已检查”模式。默认情况下,算术始终是“检查”的,这意味着如果操作的结果超出类型的值范围,则调用将通过失败的断言恢复。您可以使用 切换到“未选中”模式。更多细节可以在关于 unchecked的部分中找到。2**32 - 1 unchecked { ... }
比较
比较的值是通过比较整数值获得的值。
位操作
对数字的二进制补码表示执行位运算。这意味着,例如.~int256(0) == int256(-1)
转移
移位操作的结果具有左操作数的类型,截断结果以匹配类型。右操作数必须是无符号类型,尝试按有符号类型移位会产生编译错误。
可以通过以下方式使用乘以 2 的幂来“模拟”移位。请注意,对左操作数类型的截断总是在最后执行,但没有明确提及。
-
x << y
等价于数学表达式。x * 2**y
-
x >> y
等价于数学表达式,向负无穷舍入。x / 2**y
警告
在该版本之前,负数0.5.0
右移相当于向零舍入的数学表达式,即,使用向上舍入(向零)而不是向下舍入(向负无穷大)进行右移。x >> y
x
x / 2**y
笔记
移位操作永远不会像算术运算那样执行溢出检查。相反,结果总是被截断。
加法、减法和乘法
加法、减法和乘法具有通常的语义,在上溢和下溢方面有两种不同的模式:
默认情况下,检查所有算术是否不足或溢出,但可以使用unchecked block禁用此功能,从而导致算术包装。可以在该部分中找到更多详细信息。
该表达式-x
等价于where is 的类型。它只能应用于签名类型。如果为负,则的值可以为正。二进制补码表示还有另一个警告:(T(0) - x)
T
x
-x
x
如果有,则不适合正值范围。这意味着有效,并且在检查模式下使用表达式 将导致断言失败。int x = type(int).min;
-x
unchecked { assert(-x == x); }
-x
分配
由于运算结果的类型始终是操作数之一的类型,因此整数除法始终产生整数。在 Solidity 中,除法向零舍入。这意味着.int256(-5) / int256(2) == int256(-2)
请注意,相比之下,文字除法会产生任意精度的小数值。
笔记
除以零会导致Panic 错误。无法通过 禁用此检查。unchecked { ... }
笔记
该表达式是除法导致溢出的唯一情况。在检查算术模式下,这将导致断言失败,而在包装模式下,该值将为.type(int).min / (-1)
type(int).min
模数
模运算产生操作数 除以操作数后的余数,其中和。这意味着模运算的结果与其左操作数(或零)相同,并且对负数成立:a % n
r
a
n
q = int(a / n)
r = a - (n * q)
a % n == -(-a % n)
a
-
int256(5) % int256(2) == int256(1)
-
int256(5) % int256(-2) == int256(1)
-
int256(-5) % int256(2) == int256(-1)
-
int256(-5) % int256(-2) == int256(-1)
笔记
带零的模会导致恐慌错误。无法通过 禁用此检查。unchecked { ... }
求幂
求幂仅适用于指数中的无符号类型。求幂的结果类型始终等于基数的类型。请注意它足够大以容纳结果并为潜在的断言失败或包装行为做好准备。
笔记
在检查模式下,求幂只对小基数使用相对便宜的exp
操作码。对于 的情况x**3
,表达式x*x*x
可能更便宜。在任何情况下,gas 成本测试和优化器的使用都是可取的。
笔记
请注意,0**0
EVM 将其定义为1
.