Einführung
Willkommen, Gophers, zu diesem neuen Kapitel. In diesem Abschnitt werden wir etwas über numerische Datentypen lernen. Der Inhalt umfasst häufig verwendete Integer-Typen (ganzzahlige Datentypen), Floating-Point-Typen (Gleitkommazahlen), Boolean-Typen (boolesche Datentypen) sowie komplexe Zahlen und die in Version 1.13 eingeführte Literalwert-Syntax (Literal Value Syntax).
Wissenspunkte:
- Integer-Typen (ganzzahlige Datentypen)
- Floating-Point-Typen (Gleitkommazahlen)
- Boolean-Typen (boolesche Datentypen)
- Komplexe Zahlen
- Literalwert-Syntax (Literal Value Syntax)
Ganzzahlen (Integers)
Integer (Ganzzahlen) lassen sich grob in zwei Kategorien einteilen: Unsigned Integer (vorzeichenlose Ganzzahlen) und Signed Integer (vorzeichenbehaftete Ganzzahlen). Signed Integer (vorzeichenbehaftete Ganzzahlen) werden am häufigsten verwendet.
Unsigned (vorzeichenlos) bedeutet, dass sie nur nicht-negative Zahlen (0 und positive Zahlen) darstellen können, während Signed Integer (vorzeichenbehaftete Zahlen) sowohl negative als auch nicht-negative Zahlen darstellen können.
Unsigned Integer (vorzeichenlose Ganzzahlen) lassen sich in vier Größen unterteilen: 8 Bit, 16 Bit, 32 Bit und 64 Bit, dargestellt durch uint8, uint16, uint32 bzw. uint64. Die entsprechenden Signed Integer (vorzeichenbehafteten Ganzzahlen) sind int8, int16, int32 und int64. Die folgende Tabelle zeigt die verschiedenen Bereiche, die von jedem Typ dargestellt werden:
| Typ | Beschreibung | Bereich |
|---|---|---|
| uint8 | 8-Bit Unsigned Integer (vorzeichenlose 8-Bit-Ganzzahl) | 0 bis 255 |
| int8 | 8-Bit Signed Integer (vorzeichenbehaftete 8-Bit-Ganzzahl) | -128 bis 127 |
| uint16 | 16-Bit Unsigned Integer (vorzeichenlose 16-Bit-Ganzzahl) | 0 bis 65535 |
| int16 | 16-Bit Signed Integer (vorzeichenbehaftete 16-Bit-Ganzzahl) | -32768 bis 32767 |
| uint32 | 32-Bit Unsigned Integer (vorzeichenlose 32-Bit-Ganzzahl) | 0 bis 4294967295 |
| int32 | 32-Bit Signed Integer (vorzeichenbehaftete 32-Bit-Ganzzahl) | -2147483648 bis 2147483647 |
| uint64 | 64-Bit Unsigned Integer (vorzeichenlose 64-Bit-Ganzzahl) | 0 bis 18446744073709551615 |
| int64 | 64-Bit Signed Integer (vorzeichenbehaftete 64-Bit-Ganzzahl) | -9223372036854775808 bis 9223372036854775807 |
Nehmen wir uint8 und int8 als Beispiele. Sie sind beide 8-Bit-Integer (8-Bit-Ganzzahlen) und können 256 Werte darstellen. Im Unsigned Integer-Typ (vorzeichenlosen Ganzzahltyp) uint8 reicht der darstellbare Bereich von 0 bis 255, während im Signed Integer-Typ (vorzeichenbehafteten Ganzzahltyp) int8 der darstellbare Bereich von -128 bis 127 reicht.
Zusätzlich zu den oben genannten 8 Typen gibt es drei weitere spezielle Integer-Typen (Ganzzahltypen), uint, int und uintptr, wobei uint und int auf verschiedenen Plattformen unterschiedliche Bereiche darstellen können und uintptr zum Speichern von Pointer-Adressen (Zeigeradressen) verwendet wird.
| Typ | Bereich |
|---|---|
uint |
uint32 auf 32-Bit-Systemen, uint64 auf 64-Bit-Systemen |
int |
int32 auf 32-Bit-Systemen, int64 auf 64-Bit-Systemen |
uintptr |
Unsigned Integer-Typ (vorzeichenloser Ganzzahltyp) zum Speichern von Pointer-Adressen (Zeigeradressen), meist verwendet in Low-Level-Programmierung (Low-Level Programming) wie unsafe Operations (unsichere Operationen) |
Erstellen wir nun eine Datei namens integer.go, um die Verwendung von Integer (Ganzzahlen) zu demonstrieren:
cd ~/project
touch integer.go
package main
import (
"fmt"
"unsafe"
)
func main() {
// View the type of int in the current environment
// Den Typ von int in der aktuellen Umgebung anzeigen
// Declare a as the type int
// Deklariere a als Typ int
var a int
// Use unsafe.Sizeof() to output the memory size occupied by the type
// Verwende unsafe.Sizeof(), um die vom Typ belegte Speichergröße auszugeben
fmt.Printf("The type int in the current environment is %d bits\n", unsafe.Sizeof(a)*8)
var b int8 = 125
// Use the %d placeholder in fmt.Printf to output the value of the integer
// Verwende den Platzhalter %d in fmt.Printf, um den Wert des Integers auszugeben
// Use the %T placeholder in fmt.Printf to output the type of the variable
// Verwende den Platzhalter %T in fmt.Printf, um den Typ der Variablen auszugeben
fmt.Printf("The value of b is %d, and the type is %T\n", b, b)
// Integer operations
// Integer-Operationen
// Declare integers c and d, and calculate their sum
// Deklariere die Integer c und d und berechne ihre Summe
c, d := 2, 3
fmt.Printf("c + d = %d\n", c+d)
// 10 - 5
fmt.Printf("10 - 5 = %d\n", 10-5)
// 8 * 10
fmt.Printf("8 * 10 = %d\n", 8*10)
// Example of uintptr usage - storing an address
// Beispiel für die Verwendung von uintptr - Speichern einer Adresse
var ptr uintptr
x := 42
// Convert the pointer to x to uintptr
// Konvertiere den Zeiger auf x in uintptr
ptr = uintptr(unsafe.Pointer(&x))
fmt.Printf("The address of x stored in ptr is: %v\n", ptr)
}
Nach der Ausführung des Programms erhalten wir die folgende Ausgabe:
go run integer.go
The type int in the current environment is 64 bits
The value of b is 125, and the type is int8
c + d = 5
10 - 5 = 5
8 * 10 = 80
The address of x stored in ptr is: 824634818784
Erläuterung der Ausgabe:
The type int in the current environment is 64 bits: Diese Zeile zeigt, dass der Typintauf dem System, auf dem der Code ausgeführt wird, 64 Bit (oder 8 Byte) groß ist, was darauf hindeutet, dass es sich um einenint64handelt.unsafe.Sizeof(a)gibt die Größe der Variablenain Byte zurück, und die Multiplikation mit 8 wandelt sie in Bit um. Dies bedeutet, dass der Typintgrößere Integer-Werte (Ganzzahlwerte) aufnehmen kann.The value of b is 125, and the type is int8: Hier haben wir eine Variablebvom Typint8deklariert und ihr den Wert 125 zugewiesen. Die Ausgabe bestätigt dies, indem sie sowohl den Wert als auch den Datentyp anzeigt.c + d = 5,10 - 5 = 5,8 * 10 = 80: Diese Zeilen zeigen grundlegende arithmetische Integer-Operationen (Ganzzahloperationen): Addition, Subtraktion und Multiplikation. Die Ausgabe bestätigt die korrekten Ergebnisse dieser Berechnungen.The address of x stored in ptr is: 824634818784: Dies demonstriert, wieuintptrzum Speichern einer Speicheradresse verwendet werden kann. Wir konvertieren einen Zeiger auf die Integer-Variable (Ganzzahlvariable)xin einenuintptr-Typ. Der tatsächliche Adresswert variiert bei jeder Ausführung des Programms. Dies ist ein fortgeschrittener Anwendungsfall, der typischerweise in unsafe Operations (unsicheren Operationen) und Systemprogrammierung vorkommt.
In dieser Datei kann die Funktion unsafe.Sizeof() verwendet werden, um die Anzahl der Bytes zu erhalten, die vom aktuellen Variablentyp belegt werden. 1 Byte (Byte) entspricht 8 Bit, sodass unsafe.Sizeof()*8 die Anzahl der vom Typ belegten Bit ermitteln kann. Aus der Ausgabe können wir ersehen, dass die Online-Umgebung 64 Bit beträgt. Der tatsächliche Typ von int in der Online-Umgebung ist int64.
Wir können den folgenden Befehl im Terminal verwenden, um die aktuelle Systemarchitektur zu ermitteln:
dpkg --print-architecture
amd64
Gleitkommazahlen (Floating-Point Numbers)
Floating-Point-Zahlen (Gleitkommazahlen) stellen reelle Zahlen mit Nachkommastellen in Go mit zwei Typen dar: float32 und float64. Der Standard-Floating-Point-Typ (Standard-Gleitkommazahltyp) ist float64.
float32 und float64 stellen unterschiedliche Genauigkeiten dar. Die Standardgenauigkeit von float64 ist höher als die von float32.
Der IEEE 754-Standard ist der am weitesten verbreitete Standard für Floating-Point-Berechnungen (Gleitkomma-Berechnungen) in Computern, und moderne CPUs unterstützen diesen Standard alle. Wie andere Programmiersprachen verwendet auch Go IEEE 754 zum Speichern von Floating-Point-Zahlen (Gleitkommazahlen).
Wir wissen, dass ein Byte in einem Computer 8 Bit speichern kann. float32 ist eine Single-Precision-Floating-Point-Zahl (einfachgenaue Gleitkommazahl) und belegt 4 Byte, also 32 Bit. float64 ist eine Double-Precision-Floating-Point-Zahl (doppeltgenaue Gleitkommazahl) und belegt 8 Byte, also 64 Bit.
In float32 belegt das Vorzeichenbit 1 Bit, der Exponent belegt 8 Bit und die verbleibenden 23 Bit werden zur Darstellung der Mantisse verwendet.
In float64 belegt das Vorzeichenbit ebenfalls 1 Bit, der Exponent belegt 11 Bit und die verbleibenden 52 Bit werden zur Darstellung der Mantisse verwendet.
Der maximale Wert, den float32 darstellen kann, beträgt in wissenschaftlicher Notation ungefähr 3,4e+38, und der minimale Wert beträgt 1,4e-45. Der maximale Wert, den float64 darstellen kann, beträgt ungefähr 1,8e+308, und der minimale Wert beträgt 4,9e-324. Wir können sehen, dass der Bereich der Floating-Point-Werte (Gleitkommawerte) von sehr klein bis sehr groß reichen kann.
Wir können die Konstante math.MaxFloat32 verwenden, um den maximalen Wert in float32 darzustellen. Verwenden Sie die Konstante math.MaxFloat64, um den maximalen Wert in float64 darzustellen.
Darstellung von Floating-Point-Zahlen (Gleitkommazahlen)
Bei der Ausgabe von Floating-Point-Zahlen (Gleitkommazahlen) können wir den Platzhalter %f der Funktion Printf des Pakets fmt verwenden. Hier ist ein Beispiel:
cd ~/project
touch float.go
package main
import (
"fmt"
"math"
)
func main() {
// Output without exponential form
// Ausgabe ohne Exponentialdarstellung
fmt.Printf("2.333 without exponential form: %f\n", 2.333)
fmt.Printf("Pi without exponential form: %f\n", math.Pi)
// Use %.2f to keep two decimal places for Pi
// Verwende %.2f, um zwei Dezimalstellen für Pi beizubehalten
fmt.Printf("Pi with two decimal places: %.2f\n", math.Pi)
fmt.Printf("The maximum value of float32: %f\n", math.MaxFloat32)
// Exponential form
// Exponentialdarstellung
fmt.Printf("2.333 in exponential form: %e", 2.333)
}
Führen Sie den Befehl aus und Sie sehen die folgende Ausgabe.
go run float.go
2.333 without exponential form: 2.333000
Pi without exponential form: 3.141593
Pi with two decimal places: 3.14
The maximum value of float32: 340282346638528859811704183484516925440.000000
2.333 in exponential form: 2.333000e+00
Erläuterung der Ausgabe:
2.333 without exponential form: 2.333000: Dies zeigt die Zahl2.333, die mit dem Platzhalter%fausgegeben wird. Standardmäßig zeigt der Platzhalter%f6 Stellen nach dem Dezimalkomma an, sodass2.333zu2.333000wird.Pi without exponential form: 3.141593: Diese Zeile gibt den Wert der Konstantenmath.Piaus, die eine Annäherung an die mathematische Konstante π ist. Der Platzhalter%fzeigt sie mit voller Genauigkeit an.Pi with two decimal places: 3.14: Durch die Verwendung von%.2fweisen wirfmt.Printfan, die Zahl auf zwei Stellen nach dem Dezimalkomma zu formatieren, was zu3.14führt. Dies ist sehr nützlich, wenn Sie nur eine bestimmte Genauigkeit für die Ausgabe benötigen.The maximum value of float32: 340282346638528859811704183484516925440.000000: Dies zeigt den maximalen Wert, den einfloat32darstellen kann. Beachten Sie, dass es sich um eine sehr große Zahl handelt, die bei der Ausgabe mit%fmit vielen Stellen dargestellt wird.2.333 in exponential form: 2.333000e+00: Diese Zeile zeigt, wie eine Floating-Point-Zahl (Gleitkommazahl) in Exponentialdarstellung (wissenschaftlicher Notation) mit dem Platzhalter%edargestellt wird. Dase+00am Ende gibt an, dass wir2.333000mit 10 hoch 0 multiplizieren, was einfach2.333ist. Wenn der Exponente+02wäre, würde die Zahl mit10^2(100) multipliziert, was zu233.3führen würde.
Boolesche Datentypen (Boolean Types)
Der Typ bool hat nur zwei mögliche Werte: true (wahr) oder false (falsch), wobei false der Standardwert ist. Er hat die folgenden Eigenschaften:
- Er kann nicht in andere Typen konvertiert werden, z. B. das Konvertieren eines Integers (einer Ganzzahl) in einen Boolean (einen booleschen Wert) oder das Konvertieren eines Booleans (eines booleschen Werts) in einen Integer (eine Ganzzahl).
- Er kann nicht an arithmetischen Operationen teilnehmen.
Boolean-Typen (Boolesche Typen) werden normalerweise in Verbindung mit relationalen Operatoren wie =, > und < verwendet. Erstellen wir eine Datei namens bool.go, um eine Demonstration zu sehen:
cd ~/project
touch bool.go
package main
import (
"fmt"
)
func main() {
// Use the %t placeholder in fmt.Printf to represent a boolean value
// Verwende den Platzhalter %t in fmt.Printf, um einen booleschen Wert darzustellen
fmt.Printf("Is 3 equal to 2? %t\n", 3 == 2)
fmt.Printf("Is 2 equal to 2? %t\n", 2 == 2)
// Determine whether a and b are equal
// Bestimme, ob a und b gleich sind
a, b := 1, 2
fmt.Printf("a is %d, b is %d\n", a, b)
if a > b {
fmt.Println("a is greater than b")
} else if a == b {
fmt.Println("a is equal to b")
} else {
fmt.Println("b is greater than a")
}
}
Nach dem Ausführen des Programms erhalten wir die folgende Ausgabe:
go run bool.go
Is 3 equal to 2? false
Is 2 equal to 2? true
a is 1, b is 2
b is greater than a
Erläuterung der Ausgabe:
Is 3 equal to 2? false: Der Ausdruck3 == 2wird zufalseausgewertet, das dann mit dem Platzhalter%tausgegeben wird.Is 2 equal to 2? true: Der Ausdruck2 == 2wird zutrueausgewertet, das dann mit dem Platzhalter%tausgegeben wird.a is 1, b is 2: Diese Zeile gibt die zugewiesenen Werte der Integer-Variablen (Ganzzahlvariablen)aundbaus.b is greater than a: Dieif-else if-else-bedingte Anweisung wird zua < bausgewertet, was1 < 2(wahr) ist, daher wird dieelse-Anweisung ausgeführt, was dazu führt, dass das Programm "b is greater than a" ausgibt.
In diesem Programm verwenden wir zuerst %t in fmt.Printf, um einen Boolean-Wert (booleschen Wert) darzustellen, und verwenden dann die if-Anweisung, um die Beziehung zwischen zwei Werten zu bestimmen. In fmt.Printf können wir den Platzhalter %d verwenden, um einen Integer (eine Ganzzahl) darzustellen, den Platzhalter %f, um eine Floating-Point-Zahl (eine Gleitkommazahl) darzustellen, und den Platzhalter %t, um einen Boolean-Wert (einen booleschen Wert) darzustellen.
Komplexe Zahlen (Complex Numbers)
Go verfügt auch über integrierte komplexe Zahlentypen, die in die Typen complex64 und complex128 unterteilt werden können. In complex64 sind sowohl der Realteil als auch der Imaginärteil 32 Bit groß, während in complex128 sowohl der Realteil als auch der Imaginärteil 64 Bit groß sind. Wir können in Go problemlos Operationen mit komplexen Zahlen durchführen.
Erstellen Sie eine Datei namens complex.go und geben Sie den folgenden Code ein:
cd ~/project
touch complex.go
package main
import (
"fmt"
)
func main() {
// Initialize complex numbers in different ways
// Initialisiere komplexe Zahlen auf verschiedene Arten
c1 := complex(3, 1)
c2 := 4 + 5i
// Complex number operations
// Operationen mit komplexen Zahlen
c3 := c1 + c2
c4 := c1 * c2
// Use the real() function to obtain the real part of a complex number, and the imag() function to obtain the imaginary part of a complex number
// Verwende die Funktion real(), um den Realteil einer komplexen Zahl zu erhalten, und die Funktion imag(), um den Imaginärteil einer komplexen Zahl zu erhalten
fmt.Printf("The real part of c1 is %v, the imaginary part is %v\n", real(c1), imag(c1))
// %v in fmt.Printf can be used to represent complex numbers
// %v in fmt.Printf kann verwendet werden, um komplexe Zahlen darzustellen
fmt.Printf("c1 + c2 is %v\n", c3)
fmt.Printf("c1 * c2 is %v\n", c4)
}
Nach dem Ausführen des Programms erhalten wir die folgende Ausgabe:
go run complex.go
The real part of c1 is 3, the imaginary part is 1
c1 + c2 is (7+6i)
c1 * c2 is (7+19i)
Erläuterung der Ausgabe:
The real part of c1 is 3, the imaginary part is 1: Die Funktionreal(c1)extrahiert den Realteil der komplexen Zahlc1, der3ist, undimag(c1)extrahiert den Imaginärteil vonc1, der1ist. Diese Werte werden dann mit dem Platzhalter%vausgegeben.c1 + c2 is (7+6i): Diese Zeile zeigt das Ergebnis der Addition der komplexen Zahlenc1undc2.c1ist als3 + 1iundc2als4 + 5idefiniert. Das separate Addieren der Real- und Imaginärteile ergibt(3 + 4) + (1 + 5)ioder7 + 6i.c1 * c2 is (7+19i): Diese Zeile zeigt das Ergebnis der Multiplikation der komplexen Zahlenc1undc2.(3 + 1i) * (4 + 5i)wird als(3*4 - 1*5) + (3*5 + 1*4)iberechnet, was sich zu(12-5) + (15+4)iund schließlich zu7+19ivereinfacht.
In diesem Programm haben wir demonstriert, wie man komplexe Zahlen mit der Funktion complex und den Operatoren + und * initialisiert und Operationen mit ihnen durchführt. real() und imag() werden verwendet, um den Real- bzw. Imaginärteil einer komplexen Zahl zu extrahieren. Das Verb %v in fmt.Printf wird als allgemeiner Platzhalter verwendet, um komplexe Zahlen anzuzeigen.
Literalwert-Syntax (Literal Value Syntax)
In Version 1.13 führte Go die Numeric Literal Syntax (Numerische Literalwert-Syntax) ein. Sie definiert die Darstellung von Zahlen in verschiedenen Zahlensystemen. Sehen wir uns die Regeln an.
- Binär (Binary): Füge
0bvor der Ganzzahl (Integer) hinzu. Zum Beispiel ist0b101äquivalent zu5im Dezimalsystem. - Oktal (Octal): Füge
0ooder0Ovor der Ganzzahl (Integer) hinzu. Zum Beispiel ist0o11äquivalent zu9im Dezimalsystem. - Hexadezimal (Hexadecimal): Füge
0xoder0Xvor der Ganzzahl (Integer) hinzu. Zum Beispiel ist0x1bäquivalent zu27im Dezimalsystem. - Verwende
_, um Ziffern in der Ganzzahl (Integer) zu trennen, zum Beispiel ist0b1000_0100_0010_0001äquivalent zu0b1000010000100001. Dies kann die Lesbarkeit verbessern.
Lass es uns im Detail demonstrieren:
cd ~/project
touch literals.go
package main
import "fmt"
func main() {
// Binary, add 0b at the beginning
// Binär, füge 0b am Anfang hinzu
var a int = 0b101
fmt.Printf("Binary a is %b, decimal is %d\n", a, a)
// Octal, add 0o or 0O at the beginning
// Oktal, füge 0o oder 0O am Anfang hinzu
var b int = 0o11
fmt.Printf("Octal b is %o, decimal is %d\n", b, b)
// Hexadecimal, add 0x or 0X at the beginning
// Hexadezimal, füge 0x oder 0X am Anfang hinzu
var c int = 0x1b
fmt.Printf("Hexadecimal c is %x, decimal is %d\n", c, c)
// Use separators
// Verwende Trennzeichen
d := 0b1000_0100_0010_0001
e := 0b1000010000100001
if d == e {
fmt.Println("d is equal to e")
}
}
Nach dem Ausführen des Programms erhalten wir die folgende Ausgabe:
go run literals.go
Binary a is 101, decimal is 5
Octal b is 11, decimal is 9
Hexadecimal c is 1b, decimal is 27
d is equal to e
Erläuterung der Ausgabe:
Binary a is 101, decimal is 5: Diese Zeile zeigt die binäre Darstellung von0b101, die101ist, und ihr dezimales Äquivalent ist5. Der Platzhalter%bzeigt den Binärwert vonaan, während%ddie dezimale Darstellung anzeigt.Octal b is 11, decimal is 9: Die Oktalzahl0o11ist äquivalent zu1*8^1 + 1*8^0 = 8 + 1 = 9im Dezimalsystem. Der Platzhalter%ozeigt die oktale Darstellung vonban, und%dzeigt ihren Dezimalwert an.Hexadecimal c is 1b, decimal is 27: Die Hexadezimalzahl0x1bist äquivalent zu1*16^1 + 11*16^0 = 16 + 11 = 27im Dezimalsystem. Der Platzhalter%xzeigt die hexadezimale Darstellung voncan, und%dzeigt ihren Dezimalwert an.d is equal to e: Dies zeigt, dass das binäre Literal (Binary Literal)0b1000_0100_0010_0001den gleichen Wert wie0b1000010000100001hat. Die Unterstriche dienen lediglich der Lesbarkeit und ändern den Wert der Zahl nicht. Dieif-Bedingung wird korrekt alstrueausgewertet.
In diesem Programm haben wir die Deklaration und Ausgabe verschiedener Zahlensysteme sowie die Verwendung von Trennzeichen demonstriert. In fmt.Printf haben wir verschiedene Platzhalter verwendet, um verschiedene Zahlensysteme darzustellen. Zum Beispiel steht %b für Binär und %x für Hexadezimal. Das Beherrschen dieser wird die Programmiereffizienz verbessern.
Zusammenfassung
Lassen Sie uns zusammenfassen, was wir in diesem Abschnitt gelernt haben:
- Ganze Zahlen (Integers) können in vorzeichenbehaftete (signed) und vorzeichenlose (unsigned) ganze Zahlen unterteilt werden.
- Die Standard-Integer-Typen
intunduinthaben Bereiche, die von der Plattform abhängen. - Darstellung von Gleitkommazahlen (Floating-point numbers)
- Verwendung von komplexen Zahlen
- Einführung in die Literalwert-Syntax (Literal Value Syntax)
- Verwendung verschiedener Platzhalter
In diesem Abschnitt haben wir gängige Integer-Typen, Gleitkommatypen und boolesche Typen erklärt und demonstriert. Wir haben ihre Größen, Bereiche und Verwendung besprochen. Wir haben auch komplexe Zahlen und Literal-Konstanten eingeführt. Numerische Typen sind der Eckpfeiler von Go-Programmen, und es ist wichtig, dass Lernende sie gut studieren.



