Integers

Zig has signed and unsigned integers of various sizes:

const std = @import("std");
const print = std.debug.print;

pub fn main() void {
    // 64-bit signed integer
    const a: i64 = 1;
    const b: i64 = -2;
    print("{} + {} = {}\n", .{ a, b, a + b });

    // 64-bit unsigned integer
    const c: u64 = 3;
    const d: u64 = 4;
    print("{} + {} = {}\n", .{ c, d, c + d });

    // arbitrary bit-width integers
    const e: u4 = 6;
    const f: i12 = -100;
    print("{} + {} = {}\n", .{ e, f, e + f });

    // hexadecimal, octal, and binary numbers
    print("hex {x} is {}\n", .{ 0x100, 0x100 });
    print("octal {o} is {}\n", .{ 0o100, 0o100 });
    print("binary {b} is {}\n", .{ 0b100, 0b100 });

    // _ separator for readability
    print("one billion: {}\n", .{1_000_000_000});
}
$ zig run integers.zig 
1 + -2 = -1
3 + 4 = 7
6 + -100 = -94
hex 100 is 256
octal 100 is 64
binary 100 is 4
one billion: 1000000000

Integers are automatically converted to a bigger type, for example i16 to i32. For other cases we need @intCast:

const std = @import("std");
const print = std.debug.print;

pub fn main() void {
    const a: i16 = 100;
    const b: i32 = a;
    const c = a + b;
    print("c: {} is {}\n", .{ @TypeOf(c), c });

    const d: u16 = 100;
    const e: u8 = @intCast(d);
    const f: i16 = @intCast(d);
    print("{} {} {}\n", .{ d, e, f });
}
$ zig run integers-2.zig 
c: i32 is 200
100 100 100

Attempting to convert a number that’s out of range of the new type is checked illegal behavior.

Next example: Integer Operators.