Zig 追求的是显式性(Explicitness)和对硬件行为的精确控制。
类型
整数
Zig 支持任意位宽的整数。通过在 u(无符号)或 i(有符号)后加上数字即可定义,例如 i7 代表有符号的 7 位整数。整数类型允许的最大位宽为 65535。
- 硬件对齐:当需要操作非标准硬件(如网络协议中的 3-bit 标志位或特定的 FPGA 寄存器)时,能极大减少位掩码(bit-masking)的痛苦。
- 类型安全:编译器会确保不会意外地将一个
u4的值存入期待u3的变量中。
usize 和 isize 的大小取决于目标 CPU 架构:32 位系统上是 32 位,64 位系统上则是 64 位。
const u3 = u3; // 3位无符号整数 (0-7)
const i12 = i12; // 12位有符号整数
const u128 = u128; // 128位
浮点数
浮点数类型包括 f16、f32、f64、f80、f128,以及 c_longdouble(对应 C ABI 的 long double)。
comptime_float 具有 f128 的精度和运算能力。
浮点字面量可以隐式转换为任意浮点类型。如果浮点字面量没有小数部分,它还可以隐式转换为任意整数类型。
Zig 在浮点数处理上非常谨慎,默认遵循 IEEE 754 标准(strict模式),但在特定作用域内允许性能优化。
- 显式浮点模式:默认情况(strict模式)下,编译器不允许进行可能改变精度的重排(如将
(a + b) + c优化为a + (b + c))。@setFloatMode(.optimized)下允许编译器为了性能进行激进优化,相当于 GCC 的-ffast-math标志。 - 编译时常量表达式 (comptime):Zig 的
comptime允许在编译期以无限精度进行数值计算,只有在最终赋值给运行时变量时,才会根据目标类型进行截断或舍入。
操作
显示转换
Zig 禁止任何可能导致精度损失的隐式转换。
- 隐式类型提升 (Type Promotion):仅当转换是安全且无损时(例如
u8转u16),才允许隐式发生。
除法运算符 / 处理整数时,如果除数为 0 且在安全模式下,会直接触发 Panic。 对于浮点数,它遵循 IEEE 754,产生 inf 或 NaN。
类型强制转换
| 内置函数 | 说明 |
|---|---|
@as(T, value) | 安全类型标注。将 value强制转为类型 T。如果转换会损失信息或破坏类型规则,则编译报错;适用于向上转型(如 u8 -> u16) |
@intCast(T, value) | 整数类型强制转换。在整数类型间转换,不检查值的合理性。在安全构建模式下,如果 value 超出 T 的范围会 panic;在 ReleaseFast 下会静默截断。 |
@floatCast(T, value) | 浮点数类型强制转换。在不同浮点类型(如 f64 -> f32)间转换,可能损失精度。 |
@truncate(T, value) | 截断。将整数 value 的高位截断,以匹配目标类型 T 的位宽。 |
@bitCast(T, value) | 按位重解释。将一个值的底层二进制表示不修改任何位地解释为另一个类型。要求源类型和目标类型的大小相同。 |
@floatFromInt(value) | 将整数安全地转换为浮点数。 |
@intFromFloat(value) | 将浮点数转换为整数。如果浮点值超出目标整数范围,则为可检测的非法行为。 |
溢出相关函数
这些函数返回一个元组,包含是否溢出的布尔标志和运算结果
| 内置函数 | 说明 |
|---|---|
@addWithOverflow(a, b) | 返回 struct { overflow: u1, result: T } |
@subWithOverflow(a, b) | 返回 struct { overflow: u1, result: T } |
@mulWithOverflow(a, b) | 返回 struct { overflow: u1, result: T } |
@shlWithOverflow(a, b) | 返回 struct { overflow: u1, result: T } |
在需要明确环绕或饱和行为时避免安全检查,Zig 提供了特殊的运算符变体
| 运算符 | 说明 | 行为描述 |
|---|---|---|
+%, -%, *% | 环绕算术 | 保证以二进制补码环绕(Wrap-around) 的方式处理溢出,即结果被截断到类型宽度。例如,@as(u8, 255) +% 1 的结果是 0。 |
+|, -|, *| | 饱和算术 | 保证以饱和(Saturating) 方式处理溢出,即结果会“粘”在目标类型的最大值或最小值上。例如,@as(u8, 250) +| 10 的结果是 255。 |
std.math
std.math 库提供了更丰富的数学功能,是对内置函数的补充。
- 数学常量:如
std.math.pi,std.math.e,std.math.tau,std.math.ln2等。 - 数值比较:
approxEqAbs和approxEqRel用于浮点数的近似相等比较。 - 工具函数:如
clamp(钳制),min/max(最小/最大值),gcd(最大公约数)。 - 特殊值判断:
isFinite(是否为有限值),isNaN(是否为非数值)。 - 更复杂的数学函数:如三角函数、双曲函数、指数/对数函数等。