navigation Navigation


Inhaltsverzeichnis

Int


Der Datentyp int ist in Go ein zentraler Bestandteil für die Arbeit mit Ganzzahlen. Er repräsentiert ganze Zahlen ohne Nachkommastellen und wird häufig für Zählvorgänge, Indizes und mathematische Berechnungen verwendet. Die Größe von int ist plattformabhängig und richtet sich nach der Architektur des Systems. In diesem Artikel werden die Eigenschaften, Einsatzmöglichkeiten und Besonderheiten des int-Typs in Go erläutert und durch praxisnahe Beispiele veranschaulicht.

Inhaltsverzeichnis

    Einführung

    Integer-Datentypen repräsentieren in Go ganze Zahlen. Go bietet eine reichhaltige Palette von Integer-Typen, die sich in ihrer Größe (Anzahl der Bits) und ihrem Wertebereich unterscheiden. Diese Vielfalt ermöglicht es, den optimalen Typ für spezifische Anwendungsfälle zu wählen und dabei sowohl Speichereffizienz als auch Performance zu berücksichtigen.

    Go unterscheidet zwischen signed (vorzeichenbehafteten) und unsigned (vorzeichenlosen) Integer-Typen. Signed Integers können sowohl positive als auch negative Werte speichern, während unsigned Integers nur positive Werte (einschließlich Null) aufnehmen können.

    Hier ein kleines Beispiel.

    Beispiel - Vorzeichen
    package main
    
    import "fmt"
    
    func main() {
        var signedInt int = -42
        var unsignedInt uint = 42
    }

    Signed Integer Typ

    Signed Integer-Typen verwenden das Zweierkomplement-System zur Darstellung negativer Zahlen. Das höchstwertige Bit (MSB) fungiert als Vorzeichen-Bit, wodurch sich der verfügbare Wertebereich halbiert, aber negative Zahlen dargestellt werden können.

    int8 - 8-Bit Signed Integer

    Der int8 Typ verwendet 8 Bits zur Speicherung und kann Werte von -128 bis 127 darstellen. Dieser Typ ist besonders nützlich für Anwendungen, wo Speicherplatz kritisch ist und der Wertebereich ausreicht.

    Ein kleines Beispiel dazu.

    Beispiel
    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        var small int8 = 127
        var negative int8 = -128
    
        fmt.Println(small, negative)
    
        // Grenzbereiche
        fmt.Printf("int8 range: %d bis %d\n", math.MinInt8, math.MaxInt8)
    }
    127 -128
    int8 range: -128 bis 127

    int16 - 16-Bit Signed Integer

    Der int16 Typ bietet einen Wertebereich von -32.768 bis 32.767 und ist ideal für Anwendungen, die größere Werte als int8 benötigen, aber noch speichersparend bleiben möchten.

    Hier ein kleines Beispiel.

    Beispiel
    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        var year int16 = 2025
        var altitude int16 = -400
    
        fmt.Printf("Jahr: %d\n", year)
        fmt.Printf("Höhe: %d Meter\n", altitude)
        fmt.Printf("int16 range: %d bis %d\n", math.MinInt16, math.MaxInt16)
    
        // Array von Koordinaten
        coords := [][2]int16{
            {100, 200},
            {-150, 300},
            {0, -50},
        }
        for i, coord := range coords {
            fmt.Printf("Punkt %d: x=%d, y=%d\n", i+1, coord[0], coord[1])
        }
    }
    Jahr: 2025
    Höhe: -400 Meter
    int16 range: -32768 bis 32767
    Punkt 1: x=100, y=200
    Punkt 2: x=-150, y=300
    Punkt 3: x=0, y=-50

    int32 - 32-Bit Signed Integer

    Der int32 Typ (auch als rune bekannt) hat einen Wertebereich von -2.147.483.648 bis 2.147.483.647. Dieser Typ wird häufig für Unicode-Codepoints verwendet und bietet einen ausgewogenen Kompromiss zwischen Speicherverbrauch und Wertebereich.

    Ein kleines Beispiel zu diesem Typ.

    Beispiel
    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        var population int32 = 1500000
        var bankBalance int32 = -25000
    
        fmt.Printf("Stadtbevölkerung: %d\n", population)
        fmt.Printf("Kontostand: %d\n", bankBalance)
        fmt.Printf("int32 range: %d bis %d\n", math.MinInt32, math.MaxInt32)
    
        // Unicode-Zeichen (rune ist Alias für int32)
        var unicodeChar rune = '🚀'
        fmt.Printf("Unicode-Zeichen: %c (Code: %d)\n", unicodeChar)
    
        // Große Zahlen in wissenschaftlichen Berechnungen
        distances := []int32{384400, 149597870, 1367000000}
        bodies := []string{"Mond", "Sonne", "nächster Stern"}
    
        for i, distance := range distances {
            fmt.Printf("Entfernung zu %s: %d km\n", bodies[i], distance)
        }
    }
    Stadtbevölkerung: 1500000
    Kontostand: -25000
    int32 range: -2147483648 bis 2147483647
    Unicode-Zeichen: 🚀 (Code: 128640)
    Entfernung zu Mond: 384400 km
    Entfernung zu Sonne: 149597870 km
    Entfernung zu nächster Stern: 1367000000 km

    int64 - 64-Bit Signed Integer

    Der int64 Typ bietet den größten Wertebereich für signed Integer. -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807. Dieser Typ ist ideal für sehr große Zahlen, Zeitstempel oder finanzielle Berechnungen mit hoher Präzision.

    Auch hier ein kleines Beispiel.

    Beispiel
    package main
    
    import (
        "fmt"
        "math"
        "time"
    )
    
    func main() {
        var worldPopulation int64 = 8000000000
        var nanoseconds int64 = time.Now().UnixNano()
    
        fmt.Printf("Weltbevölkerung: %d\n", worldPopulation)
        fmt.Printf("Aktuelle Zeit in ns: %d\n", nanoseconds)
        fmt.Printf("int64 range: %d bis %d\n", math.MinInt64, math.MaxInt64)
    
        // Finanzberechnungen in Cents
        prices := []int64{199, 2999, 50000}
        items := []string{"Kaffee", "Laptop", "Auto-Anzahlung"}
    
        for i, price := range prices {
            euros := float64(price) / 100
            fmt.Printf("%s: %.2f EUR (%d Cents)\n", items[i], euros, price)
        }
    }
    Kaffee: 1.99 EUR (199 Cents)
    Laptop: 29.99 EUR (2999 Cents)
    Auto-Anzahlung: 500.00 EUR (50000 Cents)

    Unsigned Integer-Typen

    Unsigned Integer-Typen können nur positive Werte (einschließlich Null) speichern, haben aber dadurch doppelt so großen positiven Wertebereich wie ihre signed Gegenstücke. Sie sind ideal für Zähler, Indizes, Größenangaben oder andere Werte, die definitionsgemäß nicht negativ sein können.

    uint8 - 8-Bit Unsigned Integer

    Der uint8 Typ (auch als byte bekannt) kann Werte von 0 bis 255 speichern. Dieser Typ wird sehr häufig für die Darstellung von Bytes, Farb-RGB-Werten oder anderen 8-Bit-Daten verwendet.

    Beispiel - uint8
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var age uint8 = 25
        var redValue uint8 = 255
    
        fmt.Printf("Alter: %d Jahre\n", age)
        fmt.Printf("Rot-Wert: %d\n", redValue)
    
        type RGB struct {
            Red uint8
            Green uint8
            Blue uint8
        }
    
        colors := []RGB{
            {255, 0, 0},
            {0, 255, 0},
            {0, 0, 255},
            {255, 255, 0},
            {128, 128, 128},
        }
    
        colorNames := []string{
            "Rot",
            "Grün",
            "Blau",
            "Gelb",
            "Grau",
        }
    
        for i, color := range colors {
            fmt.Printf("%s: RGB(%d, %d, %d)\n", colorNames[i], color.Red, color.Green, color.Blue)
        }
    }
    Alter: 25 Jahre
    Rot-Wert: 255
    Rot: RGB(255, 0, 0)
    Grün: RGB(0, 255, 0)
    Blau: RGB(0, 0, 255)
    Gelb: RGB(255, 255, 0)
    Grau: RGB(128, 128, 128)

    uint16 - 16-Bit Unsigned Integer

    Der uint16 Typ speichert Werte von 0 bis 65.535 und wird oft für Port-Nummern, kleinere IDs oder Audio-Samples verwendet.

    Beispiel - uint8
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var port uint16 = 8080
        var studentId uint16 = 12345
    
        fmt.Printf("Server-Port: %d\n", port)
        fmt.Printf("Studenten-ID: %d\n", studentId)
    
        // Netzwerk-Ports
        standardPorts := map[string]uint16{
            "HTTP": 80,
            "HTTPS": 443,
            "FTP": 21,
            "SSH": 22,
            "DNS": 53,
        }
    
        fmt.Println("Standard-Ports")
        for service, port := range standardPorts {
            fmt.Printf("\t%s: %d\n", service, port)
        }
    
        // Audio-Sample Werte (16-bit Audio)
        audioSamples := []uint16{0, 16384, 32768, 49152, 65535}
        fmt.Println("Audio-Samples (16-bit:)")
        for i, sample := range audioSample {
            percentage := float64(sample) / 65535 * 100
            fmt.Printf("\tSample %d: %d (%.1f%%)\n", i, sample, percentage)
        }
    }
    Server-Port: 8080
    Studenten-ID: 12345
    Standard-Ports
        HTTP: 80
        HTTPS: 443
        FTP: 21
        SSH: 22
        DNS: 53
    Audio-Samples (16-bit:)
        Sample 0: 0 (0.0%)
        Sample 1: 16384 (25.0%)
        Sample 2: 32768 (50.0%)
        Sample 3: 49152 (75.0%)
        Sample 4: 65535 (100.0%)

    uint32 - 32-Bit Unsigned Integer

    Der uint32 Typ kann Werte von 0 bis 4.294.967.295 speichern und wird häufig für IP-Adressen, große IDs oder Zeitstempel verwendet.

    Beispiel - uint32
    package main
    
    import (
        "fmt"
        "net"
    )
    
    func main() {
        var timestamp uint32 = uint32(time.Now().Unix())
        var userId uint32 = 1000000
    
        fmt.Printf("Unix-Timestamp: %d\n", timestamp)
        fmt.Printf("Benutzer-ID: %d\n", userId)
    
        // IP-Adresse als uint32 (IPv4)
        ip := net.ParseIP("192.168.1.1").To4()
        if ip != nil {
            ipAsUint32 := uint32(ip[0])<<24 + uint32(ip[1])<<16 + uint32(ip[2])<<8 + uint32(ip[3])
            fmt.Printf("IP %s als uint32: %d\n", ip, ipAsUint32)
    
            // Zurück zur IP
            a := byte(ipAsUint32 >> 24)
            b := byte(ipAsUint32 >> 16)
            c := byte(ipAsUint32 >> 8)
            d := byte(ipAsUint32)
    
            fmt.Printf("uint32 %d als IP: %d.%d.%d.%d\n", ipAsUint32, a, b, c, d)
        }
    }
    Unix-Timestamp: 1758555404
    Benutzer-ID: 1000000
    IP 192.168.1.1 als uint32: 3232235777
    uint32 3232235777 als IP: 192.168.1.1

    uint64 - 64-Bit Unsigned Integer

    Der uint64 Typ bietet den größten Wertebereich: 0 bis 18.446.744.073.709.551.615. Er wird für sehr große Zähler, Dateigrößen oder präzise Zeitberechnungen verwendet.

    Beispiel - uint32
    package main
    
    import (
        "fmt"
        "math"
        "time"
    )
    
    func main() {
        var fileSize uint64 = 5368709120 // 5 GB
        var microTimestamp uint64 = uint64(time.Now().UnixMicro())
    
        fmt.Printf("Dateigröße: %d Bytes\n", fileSize)
        fmt.Printf("Mikrosekunden-Timestamp: %d\n", microTimestamp)
    
        fmt.Printf("uint64 Maximum: %d\n", uint64(math.MaxUint64))
    
        // Dateigrößen in verschiedenen Einheiten
        fileSizes := []uint64{
            1024,           // 1 KB
            1048576,        // 1 MB
            1073741824,     // 1 GB
            1099511627776,  // 1 TB
        }
    
        units := []string{"KB", "MB", "GB", "TB"}
    
        fmt.Println("Dateigrößen")
        for i, size := range fileSizes {
            fmt.Printf("\t1 %s = %d Bytes\n", units[i], size)
        }
    }
    Dateigröße: 5368709120 Bytes
    Mikrosekunden-Timestamp: 1758556086872419
    uint64 Maximum: 18446744073709551615
    Dateigrößen
        1 KB = 1024 Bytes
        1 MB = 1048576 Bytes
        1 GB = 1073741824 Bytes
        1 TB = 1099511627776 Bytes

    Plattformspezifische Typen

    Go bietet plattformspezifische Integer-Typen, deren Größe von der Zielarchitektur abhängt. Diese Typen passen sich automatisch an die optimale Wortbreite der jeweiligen Plattform an.

    int und uint - Plattformabhängige Integer

    Die Typen int und uint haben eine plattformabhängige Größe: 32 Bit auf 32-Bit-Systemen und 64 Bit auf 64-Bit-Systemen. Diese Typen sind die Standardwahl für die meisten Integer-Operationen, da sie optimal zur Architektur des Zielsystems passen.

    Beispiel
    package main
    
    import (
        "fmt"
        "math"
        "runtime"
        "unsafe"
    )
    
    func main() {
        var standardInt int = 42
        var standardUint uint = 42
    
        // Größe der plattformabhängigen Typen ermitteln
        intSize := unsafe.Sizeof(standardInt) * 8
        uintSize := unsafe.Sizeof(standardUint) * 8
    
        fmt.Printf("Aktuelle Plattform: %s/%s\n", runtime.GOOS, runtime,.GOARCH)
        fmt.Printf("int Größe: %d Bit\n", intSize)
        fmt.Printf("uint Größe: %d Bit\n", uintSize)
    
        // Maximum ausgeben
        fmt.Printf("Maximaler int-Wert: %d\n", int(math.MaxInt))
        fmt.Printf("Maximaler uint-Wert: %d\n", uint(math.MaxUint))
    }
    Aktuelle Plattform: darwin/arm64
    int Größe: 64 Bit
    uint Größe: 64 Bit
    Maximaler int-Wert: 9223372036854775807
    Maximaler uint-Wert: 18446744073709551615

    uintptr - Pointer-Arithmetik

    Der uintptr Typ ist groß genug, um jeden Pointer-Wert zu speichern. Er wird hauptsächlich für Pointer-Arithmetik und die Interaktion mit C-Code verwendet.

    Beispiel - uintptr
    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    func main() {
        var x int = 42
        ptr := &x
    
        // Pointer zu uintptr konvertieren
        addr := uintptr(unsafe.Pointer(ptr))
    
        fmt.Printf("Variable x: %d\n", x)
        fmt.Printf("Adresse von x: %p\n", ptr)
        fmt.Printf("Adresse als uintptr: %d (0x%x)\n", addr, addr)
    
        // uintptr Größe
        fmt.Printf("uintptr Größe: %d Bit\n", unsafe.Sizeof(addr)*8)
    
    }
    Variable x: 42
    Adresse von x: 0x1400000e0c8
    Adresse als uintptr: 1374389592264 (0x1400000e0c8)
    uintptr Größe: 64 Bit