ZetCode

Golang uint32 type

last modified May 8, 2025

This tutorial explains how to use the uint32 built-in type in Go. We'll cover basic usage with practical examples of working with 32-bit unsigned integers.

The uint32 type represents 32-bit unsigned integers in Go. It can store values from 0 to 4,294,967,295. This type is useful when you need to work with positive numbers and conserve memory.

In Go, uint32 is part of the family of unsigned integer types. It's commonly used for binary data, network protocols, and when working with hardware that uses 32-bit values.

Basic uint32 declaration and initialization

The simplest way to use uint32 is to declare and initialize a variable. This example shows basic declaration and arithmetic operations.
Note: uint32 values cannot be negative.

basic_uint32.go
package main

import "fmt"

func main() {

    var a uint32 = 42
    var b uint32 = 1000
    c := uint32(50000) // Type conversion
    
    sum := a + b
    product := b * c
    
    fmt.Println("Sum:", sum)
    fmt.Println("Product:", product)
    fmt.Println("Difference:", b-a)
}

We declare three uint32 variables and perform basic arithmetic operations. The type conversion shows how to create a uint32 from a literal.

Working with binary data

uint32 is often used when working with binary data and bitwise operations. This example demonstrates bit manipulation with uint32 values.

bitwise_operations.go
package main

import "fmt"

func main() {

    var flags uint32 = 0
    
    // Set bits
    flags |= 1 << 0 // Set bit 0
    flags |= 1 << 3 // Set bit 3
    
    // Check bits
    if flags&(1<<0) != 0 {
        fmt.Println("Bit 0 is set")
    }
    
    // Clear bit
    flags &^= 1 << 3
    
    fmt.Printf("Flags in binary: %032b\n", flags)
    fmt.Printf("Flags in hex: 0x%08X\n", flags)
}

This shows how to set, check, and clear individual bits in a uint32 value. The printf format verbs display the value in binary and hexadecimal.

Network byte order conversion

uint32 is commonly used in network programming. This example demonstrates host-to-network and network-to-host byte order conversion.

network_byte_order.go
package main

import (
    "encoding/binary"
    "fmt"
)

func main() {

    hostValue := uint32(0x12345678)
    
    // Convert to network byte order (big-endian)
    buf := make([]byte, 4)
    binary.BigEndian.PutUint32(buf, hostValue)
    fmt.Printf("Network order: % X\n", buf)
    
    // Convert back to host order
    networkValue := binary.BigEndian.Uint32(buf)
    fmt.Printf("Host order: 0x%08X\n", networkValue)
    
    // Check if system is little-endian
    if binary.LittleEndian.Uint32([]byte{0x78, 0x56, 0x34, 0x12}) == hostValue {
        fmt.Println("System is little-endian")
    }
}

The example shows how to convert uint32 values between host and network byte order. This is essential for network protocol implementations.

Using uint32 in structs

uint32 is often used in structs for binary data formats. This example demonstrates using uint32 in a struct that mimics a file header.

struct_usage.go
package main

import (
    "encoding/binary"
    "fmt"
    "log"
)

type FileHeader struct {
    Magic   uint32
    Version uint32
    Size    uint32
    CRC     uint32
}

func main() {

    data := []byte{
        0x89, 'P', 'N', 'G', // Magic
        0x00, 0x00, 0x00, 0x01, // Version
        0x00, 0x01, 0x86, 0xA0, // Size
        0x12, 0x34, 0x56, 0x78, // CRC
    }
    
    var header FileHeader
    
    // Parse binary data into struct
    err := binary.Read(bytes.NewReader(data), binary.BigEndian, &header)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Magic: 0x%08X\n", header.Magic)
    fmt.Printf("Version: %d\n", header.Version)
    fmt.Printf("Size: %d bytes\n", header.Size)
    fmt.Printf("CRC: 0x%08X\n", header.CRC)
}

The struct uses uint32 fields to match a binary file format. The binary package reads the data directly into the struct fields.

Handling uint32 overflow

Since uint32 has a fixed range, operations can overflow. This example shows how to detect and handle uint32 overflow situations.

overflow_handling.go
package main

import (
    "errors"
    "fmt"
    "math"
)

func safeAdd(a, b uint32) (uint32, error) {
    if math.MaxUint32-a < b {
        return 0, errors.New("uint32 overflow")
    }
    return a + b, nil
}

func main() {

    max := uint32(math.MaxUint32)
    
    // This will overflow
    result, err := safeAdd(max, 1)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
    
    // This will work
    result, err = safeAdd(max-10, 5)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
    
    // Wrapping behavior
    wrapped := max + 1
    fmt.Println("Wrapped value:", wrapped)
}

The safeAdd function checks for potential overflow before performing the addition. The example also shows the default wrapping behavior of uint32.

Source

Go language specification

This tutorial covered the uint32 type in Go with practical examples of its usage in various scenarios including binary operations and network programming.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.