Basic Data Types

for Zig 0.15.2 Buy

Basic Data Types

You’ve probably already noticed, from the previous examples, that Zig uses data types in a very strict way. In some cases, Zig can automatically determine these types. This is technically called type inference.

 const n_x = 1;

Here, for example, Zig infers that n_x is an integer number, but we can also specify the type explicitly.

 const n_x: u1 = 1;

Type u1? Yes. The u comes from unsigned (an unsigned integer), and the 1 indicates the number of bits the value will use in memory. A bit is the smallest unit of data representation in memory. It can hold only two values: 0 or 1.

If we think of a bit as a box that can store either a 0 or a 1:

0

bit

It’s clear that with a single bit we can represent just a 0 or a 1 - nothing more, nothing less. Since we only have one bit, the smallest number we can represent is 0, and the largest is 1.

0

ó

1

2⁰

2⁰

Since u1 uses just one bit, if we try to assign a number greater than 1 to a u1 data type, the following will happen:

const_2.zig

const std = @import("std");

pub fn main() u8 {

    const n_a: u1 = 2;

    return n_a;

}

$ zig run const_2.zig

const_2.zig:4:21: error: type 'u1' cannot represent integer value '2'

    const n_a: u1 = 2;

                    ^

The compiler tells us that we can’t represent the value 2 with a one-bit integer.

So what can we do? How many bits do we need to represent the number 2?

There’s an old joke among programmers that goes:

There are 10 types of people - those who understand binary and those who don’t.

   const n_x: u2 = 2;

If we change the type to u2, that means we now have 2 bits for our data. That gives us four possible combinations:

  0

0

0

2⁰

1

0

1

2⁰

 2

1

0

2⁰

3

1

1

2⁰

With two bits, we can represent values from 0 up to:

              2¹ + 2⁰ = 2 + 1 = 3

In other words, values between 0 and 3.

Do you need to know all the types in detail and by heart?

To begin with, it’s enough to get familiar with: u8, i32, usize, f32, bool, and void.

To give you a global picture and help you start exploring Zig’s primitive types, here’s a summary:

Booleans

The values a boolean type can take are only two: true (True) or false (False). These, along with the boolean operators we’ll see in the next chapter, make it possible to evaluate expressions and then make different decisions in our code.

bool

True or false values

Integer (whole) numbers

Zig supports integer types of any bit size, like u3, i5, or u37. This isn’t common in other languages and lets you fine-tune memory usage to the maximum.

u8

Unsigned 8-bit integer

0 to 255

i8

Signed 8-bit integer

-128 to 127

u16

Unsigned 16-bit integer

0 to 65,535

i16

Signed 16-bit integer

-32,768 to 32,767

u32

Unsigned 32-bit integer

0 to ~4 billion

i32

Signed 32-bit integer

~ -2 billion to 2 billion

usize

Unsigned integer the size of the system (useful for counting things like bytes)

Floating-point numbers

f16

Low Precision (16 bits)

 Very compact, rarely used

f32

Medium Precision (32 bits)

 Enough for most cases

f64

High Precision (64 bits)

 High numerical accuracy

Other types

void

No value (used for functions that return nothing)

noreturn

Something that never returns (like return, unreachable)

comptime_int

Special type used only at compile time

anyerror

Any kind of error, for error handling

type

The type of types (yes, it’s strange - but useful in Zig)

Comments
Tuples and text
© 2025 - 2026 Zen of Zig