Namensräume
Varianten
Aktionen

Arithmetische Typen

Von cppreference.com
< c‎ | Sprache

(Siehe auch Typ für eine Übersicht des Typsystems und die Liste der typbezogenen Dienstprogramme, die von der C-Bibliothek bereitgestellt werden.)

Inhalt

Boolescher Typ

  • _Bool (auch zugänglich als Makro bool)(bis C23)bool(seit C23) — Typ, der einen von zwei Werten aufnehmen kann: 1 und 0 (auch zugänglich als Makros true und false)(bis C23)true und false(seit C23).

Beachten Sie, dass die Konvertierung zu _Bool(bis C23)bool(seit C23) nicht dasselbe ist wie die Konvertierung zu anderen Ganzzahl-Typen: (bool)0.5 ergibt true, während (int)0.5 ergibt 0.

(seit C99)

[bearbeiten] Zeichen-Typen

  • signed char — Typ für die Darstellung von vorzeichenbehafteten Zeichen.
  • unsigned char — Typ für die Darstellung von vorzeichenlosen Zeichen. Wird auch verwendet, um Objektrepräsentationen (roher Speicher) zu inspizieren.
  • char — Typ für die Zeichenrepräsentation. Entspricht entweder signed char oder unsigned char (welcher einer von beiden implementierungsabhängig ist und durch einen Compiler-Schalter gesteuert werden kann), aber char ist ein eigenständiger Typ, der sich von sowohl signed char als auch unsigned char unterscheidet.

Beachten Sie, dass die Standardbibliothek auch typedef-Namen wchar_t, char16_t und char32_t(seit C11) zur Darstellung von weiten Zeichen und char8_t für UTF-8-Zeichen(seit C23) definiert.

[bearbeiten] Ganzzahl-Typen

  • short int (auch zugänglich als short, kann das Schlüsselwort signed verwenden)
  • unsigned short int (auch zugänglich als unsigned short)
  • int (auch zugänglich als signed int)
Dies ist der optimalste Ganzzahl-Typ für die Plattform und garantiert mindestens 16 Bit. Die meisten aktuellen Systeme verwenden 32 Bit (siehe Datenmodelle unten).
  • unsigned int (auch zugänglich als unsigned), das vorzeichenlose Gegenstück von int, das Modulo-Arithmetik implementiert. Geeignet für Bit-Manipulationen.
  • long int (auch zugänglich als long)
  • unsigned long int (auch zugänglich als unsigned long)
  • long long int (auch zugänglich als long long)
  • unsigned long long int (auch zugänglich als unsigned long long)
(seit C99)
  • _BitInt(n) (auch zugänglich als signed _BitInt(n)), die bitgenauen vorzeichenbehafteten Ganzzahl-Typen (wobei n durch einen ganzzahligen konstanten Ausdruck ersetzt wird, der die genaue Breite bezeichnet (einschließlich des Vorzeichenbits), die nicht größer sein kann als BITINT_MAXWIDTH aus <limits.h>)
  • unsigned _BitInt(n), die bitgenauen vorzeichenlosen Ganzzahl-Typen (wobei n durch einen ganzzahligen konstanten Ausdruck ersetzt wird, der die genaue Breite bezeichnet, die nicht größer sein kann als BITINT_MAXWIDTH aus <limits.h>)
(seit C23)

Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: unsigned long long int und long int unsigned long bezeichnen denselben Typ.

Die folgende Tabelle fasst alle verfügbaren Ganzzahl-Typen und ihre Eigenschaften zusammen

Typspezifizierer Entsprechender Typ Breite in Bits nach Datenmodell
C-Standard LP32 ILP32 LLP64 LP64
char
char mindestens
8
8 8 8 8
signed char
signed char
unsigned char
unsigned char
short
short int mindestens
16
16 16 16 16
short int
signed short
signed short int
unsigned short
unsigned short int
unsigned short int
int
int mindestens
16
16 32 32 32
signed
signed int
unsigned
unsigned int
unsigned int
long
long int mindestens
32
32 32 32 64
long int
signed long
signed long int
unsigned long
unsigned long int
unsigned long int
long long
long long int
(C99)
mindestens
64
64 64 64 64
long long int
signed long long
signed long long int
unsigned long long
unsigned long long int
(C99)
unsigned long long int

Neben den minimalen Bit-Anzahlen garantiert der C-Standard, dass

1 == sizeof(char) sizeof(short) sizeof(int) sizeof(long) sizeof(long long).

Hinweis: Dies erlaubt den Extremfall, bei dem Bytes 64 Bit groß sind, alle Typen (einschließlich char) 64 Bit breit sind und sizeof für jeden Typ 1 zurückgibt.

Hinweis: Die Ganzzahl-Arithmetik ist für vorzeichenbehaftete und vorzeichenlose Ganzzahl-Typen unterschiedlich definiert. Siehe arithmetische Operatoren, insbesondere Ganzzahl-Überläufe.

[bearbeiten] Datenmodelle

Die von jeder Implementierung getroffenen Entscheidungen über die Größen der fundamentalen Typen werden kollektiv als Datenmodell bezeichnet. Vier Datenmodelle fanden weite Akzeptanz

32-Bit-Systeme

  • LP32 oder 2/4/4 (int ist 16-Bit, long und Zeiger sind 32-Bit)
  • Win16 API
  • ILP32 oder 4/4/4 (int, long und Zeiger sind 32-Bit);
  • Win32 API
  • Unix und Unix-ähnliche Systeme (Linux, Mac OS X)

64-Bit-Systeme

  • LLP64 oder 4/4/8 (int und long sind 32-Bit, Zeiger ist 64-Bit)
  • Win64 API
  • LP64 oder 4/8/8 (int ist 32-Bit, long und Zeiger sind 64-Bit)
  • Unix und Unix-ähnliche Systeme (Linux, Mac OS X)

Andere Modelle sind sehr selten. Zum Beispiel erschien ILP64 (8/8/8: int, long und Zeiger sind 64-Bit) nur in einigen frühen 64-Bit-Unix-Systemen (z.B. Unicos auf Cray).

Beachten Sie, dass exakte Ganzzahl-Typen seit C99 in <stdint.h> verfügbar sind.

[bearbeiten] Reelle Gleitkomma-Typen

C hat drei oder sechs(seit C23) Typen zur Darstellung reeller Gleitkommawerte

  • float — Gleitkommatyp mit einfacher Genauigkeit. Entspricht dem IEEE-754 binary32 Format, falls unterstützt.
  • double — Gleitkommatyp mit doppelter Genauigkeit. Entspricht dem IEEE-754 binary64 Format, falls unterstützt.
  • long double — Gleitkommatyp mit erweiterter Genauigkeit. Entspricht dem IEEE-754 binary128 Format, falls unterstützt, andernfalls dem IEEE-754 binary64-extended Format, falls unterstützt, andernfalls einem nicht-IEEE-754 erweiterten Gleitkommaformat, solange seine Genauigkeit besser ist als binary64 und sein Bereich mindestens so gut ist wie binary64, andernfalls entspricht es dem IEEE-754 binary64 Format.
    • Das binary128 Format wird von einigen HP-UX, SPARC, MIPS, ARM64 und z/OS-Implementierungen verwendet.
    • Das bekannteste IEEE-754 binary64-extended Format ist das 80-Bit x87-Format mit erweiterter Genauigkeit. Es wird von vielen x86- und x86-64-Implementierungen verwendet (eine bemerkenswerte Ausnahme ist MSVC, das long double im selben Format wie double, d.h. binary64, implementiert).
Wenn die Implementierung das Makro __STDC_IEC_60559_DFP__ vordefiniert, werden auch die folgenden Dezimal-Gleitkomma-Typen unterstützt.
Andernfalls werden diese Dezimal-Gleitkomma-Typen nicht unterstützt.
(seit C23)

Gleitkomma-Typen können spezielle Werte unterstützen

  • Unendlich (positiv und negativ), siehe INFINITY
  • das negative Null, -0.0. Es vergleicht sich gleich mit der positiven Null, ist aber in einigen arithmetischen Operationen bedeutsam, z. B. 1.0 / 0.0 == INFINITY, aber 1.0 / -0.0 == -INFINITY)
  • nicht-eine-Zahl (NaN), die sich mit nichts (einschließlich sich selbst) vergleicht. Mehrere Bit-Muster stellen NaNs dar, siehe nan, NAN. Beachten Sie, dass C keine besondere Beachtung für Signalisierungs-NaNs (gemäß IEEE-754) hat und alle NaNs als leise behandelt.

Reelle Gleitkommazahlen können mit arithmetischen Operatoren + - / * und verschiedenen mathematischen Funktionen aus <math.h> verwendet werden. Sowohl eingebaute Operatoren als auch Bibliotheksfunktionen können Gleitkomma-Ausnahmen auslösen und errno setzen, wie in math_errhandling beschrieben.

Gleitkomma-Ausdrücke können einen größeren Bereich und eine höhere Genauigkeit aufweisen, als ihre Typen anzeigen, siehe FLT_EVAL_METHOD. Zuweisung, Rückgabe und Cast erzwingen den Bereich und die Genauigkeit auf diejenige, die mit dem deklarierten Typ verbunden ist.

Gleitkomma-Ausdrücke können auch kontrahiert werden, das heißt, sie werden so berechnet, als hätten alle Zwischenwerte einen unendlichen Bereich und eine unendliche Genauigkeit, siehe #pragma STDC FP_CONTRACT.

Einige Operationen mit Gleitkommazahlen werden durch den Zustand der Gleitkomma-Umgebung beeinflusst und ändern diesen (am bemerkenswertesten die Rundungsrichtung).

Implizite Konvertierungen sind zwischen reellen Gleitkomma-Typen und Ganzzahl-, komplexen und imaginären Typen definiert.

Siehe Grenzen von Gleitkomma-Typen und die <math.h> Bibliothek für zusätzliche Details, Grenzen und Eigenschaften der Gleitkomma-Typen.

Komplexe Gleitkomma-Typen

Komplexe Gleitkomma-Typen modellieren die mathematische komplexe Zahl, d.h. die Zahlen, die als Summe einer reellen Zahl und einer reellen Zahl multipliziert mit der imaginären Einheit geschrieben werden können: a + bi

Die drei komplexen Typen sind

Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: long double complex, complex long double und sogar double complex long bezeichnen denselben Typ.

#include <complex.h>
#include <stdio.h>
 
int main(void)
{
    double complex z = 1 + 2*I;
    z = 1 / z;
    printf("1/(1.0+2.0i) = %.1f%+.1fi\n", creal(z), cimag(z));
}

Ausgabe

1/(1.0+2.0i) = 0.2-0.4i

Wenn die Makrokonstante __STDC_NO_COMPLEX__ von der Implementierung definiert wird, werden die komplexen Typen (sowie die Bibliotheksdatei <complex.h>) nicht bereitgestellt.

(seit C11)

Jeder komplexe Typ hat dieselbe Objektrepräsentation und Ausrichtungsanforderungen wie ein Array aus zwei Elementen des entsprechenden reellen Typs (float für float complex, double für double complex, long double für long double complex). Das erste Element des Arrays enthält den Realteil und das zweite Element des Arrays den Imaginärteil.

float a[4] = {1, 2, 3, 4};
float complex z1, z2;
memcpy(&z1, a, sizeof z1); // z1 becomes 1.0 + 2.0i
memcpy(&z2, a+2, sizeof z2); // z2 becomes 3.0 + 4.0i

Komplexe Zahlen können mit arithmetischen Operatoren + - * und / verwendet werden, möglicherweise gemischt mit imaginären und reellen Zahlen. Es gibt viele mathematische Funktionen für komplexe Zahlen in <complex.h>. Sowohl eingebaute Operatoren als auch Bibliotheksfunktionen können Gleitkomma-Ausnahmen auslösen und errno setzen, wie in math_errhandling beschrieben.

Inkrement- und Dekrementoperatoren sind für komplexe Typen nicht definiert.

Relationale Operatoren sind für komplexe Typen nicht definiert (es gibt keine Vorstellung von "kleiner als").

Implizite Konvertierungen sind zwischen komplexen Typen und anderen arithmetischen Typen definiert.

Um das Ein-Unendlich-Modell der komplexen Zahlenarithmetik zu unterstützen, betrachtet C jeden komplexen Wert mit mindestens einem unendlichen Teil als unendlich, auch wenn sein anderer Teil eine NaN ist, garantiert, dass alle Operatoren und Funktionen grundlegende Eigenschaften von Unendlichkeiten beachten und stellt cproj bereit, um alle Unendlichkeiten auf die kanonische zu mappen (siehe arithmetische Operatoren für die genauen Regeln).

#include <complex.h>
#include <math.h>
#include <stdio.h>
 
int main(void)
{
    double complex z = (1 + 0*I) * (INFINITY + I*INFINITY);
//  textbook formula would give
//  (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
//  but C gives a complex infinity
    printf("%f%+f*i\n", creal(z), cimag(z));
 
//  textbook formula would give
//  cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
//  but C gives  ±∞+i*nan
    double complex y = cexp(INFINITY + I*NAN);
    printf("%f%+f*i\n", creal(y), cimag(y));
}

Mögliche Ausgabe

inf+inf*i 
inf+nan*i

C behandelt auch mehrere Unendlichkeiten so, dass sie, trotz der inhärenten Einschränkungen der kartesischen Darstellung, die Richtungsinformationen nach Möglichkeit beibehalten.

die Multiplikation der imaginären Einheit mit unendlicher Realität ergibt die korrekt-vorzeichenbehaftete imaginäre Unendlichkeit: i × ∞ = i∞. Außerdem ergibt i × (∞ – i∞) = ∞ + i∞ die vernünftige Quadrante.

Imaginäre Gleitkomma-Typen

Imaginäre Gleitkomma-Typen modellieren die mathematischen imaginären Zahlen, d.h. Zahlen, die als reelle Zahl multipliziert mit der imaginären Einheit geschrieben werden können: bi Die drei imaginären Typen sind

Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: long double imaginary, imaginary long double und sogar double imaginary long bezeichnen denselben Typ.

#include <complex.h>
#include <stdio.h>
 
int main(void)
{
    double imaginary z = 3*I;
    z = 1 / z;
    printf("1/(3.0i) = %+.1fi\n", cimag(z));
}

Ausgabe

1/(3.0i) = -0.3i

Es wird zwar empfohlen, aber nicht gefordert, dass eine Implementierung, die __STDC_IEC_559_COMPLEX__ definiert, imaginäre Zahlen unterstützt. POSIX empfiehlt, zu prüfen, ob das Makro _Imaginary_I definiert ist, um die Unterstützung für imaginäre Zahlen zu identifizieren.

(bis C11)

Imaginäre Zahlen werden unterstützt, wenn __STDC_IEC_559_COMPLEX__(bis C23)__STDC_IEC_60559_COMPLEX__(seit C23) definiert ist.

(seit C11)

Jeder der drei imaginären Typen hat dieselbe Objektrepräsentation und Ausrichtungsanforderung wie sein entsprechender reeller Typ (float für float imaginary, double für double imaginary, long double für long double imaginary).

Hinweis: Trotzdem sind imaginäre Typen eigenständig und nicht kompatibel mit ihren entsprechenden reellen Typen, was Aliasing verbietet.

Imaginäre Zahlen können mit arithmetischen Operatoren + - * und / verwendet werden, möglicherweise gemischt mit komplexen und reellen Zahlen. Es gibt viele mathematische Funktionen für imaginäre Zahlen in <complex.h>. Sowohl eingebaute Operatoren als auch Bibliotheksfunktionen können Gleitkomma-Ausnahmen auslösen und errno setzen, wie in math_errhandling beschrieben.

Inkrement- und Dekrementoperatoren sind für imaginäre Typen nicht definiert.

Implizite Konvertierungen sind zwischen imaginären Typen und anderen arithmetischen Typen definiert.

Die imaginären Zahlen ermöglichen es, alle komplexen Zahlen mit der natürlichen Notation x + I*y auszudrücken (wobei I als _Imaginary_I definiert ist). Ohne imaginäre Typen können bestimmte spezielle komplexe Werte nicht natürlich erzeugt werden. Zum Beispiel, wenn I als _Complex_I definiert ist, ergibt die Schreibweise 0.0 + I*INFINITY NaN als Realteil, und CMPLX(0.0, INFINITY) muss stattdessen verwendet werden. Dasselbe gilt für Zahlen mit einer negativen Null im Imaginärteil, die bei der Arbeit mit Bibliotheksfunktionen mit Zweigfunktionen wie csqrt bedeutsam sind: 1.0 - 0.0*I ergibt den positiven Null-Imaginärteil, wenn I als _Complex_I definiert ist, und der negative Null-Imaginärteil erfordert die Verwendung von CMPLX oder conj.

Imaginäre Typen vereinfachen auch die Implementierungen; die Multiplikation einer imaginären Zahl mit einer komplexen Zahl kann bei Unterstützung von imaginären Typen geradlinig mit zwei Multiplikationen implementiert werden, anstatt mit vier Multiplikationen und zwei Additionen.

(seit C99)

[bearbeiten] Schlüsselwörter

[bearbeiten] Wertebereich

Die folgende Tabelle bietet eine Referenz für die Grenzen gängiger numerischer Darstellungen.

Vor C23 erlaubte der C-Standard jede vorzeichenbehaftete Ganzzahldarstellung, und der minimal garantierte Bereich von N-Bit-Ganzzahlen mit Vorzeichen war von -(2N-1
-1)
bis +2N-1
-1
(z. B. -127 bis 127 für einen vorzeichenbehafteten 8-Bit-Typ), was den Grenzen von Einerkomplement oder Vorzeichen und Betrag entspricht.

Alle gängigen Datenmodelle (einschließlich aller ILP32, LP32, LP64, LLP64) und fast alle C-Compiler verwenden jedoch die Zweierkomplementdarstellung (die einzigen bekannten Ausnahmen sind einige Compiler für UNISYS), und ab C23 ist dies die einzige vom Standard zugelassene Darstellung mit dem garantierten Bereich von -2N-1
bis +2N-1
-1
(z. B. -128 bis 127 für einen vorzeichenbehafteten 8-Bit-Typ).

Typ Größe in Bits Format Wertebereich
Ungefähr Exakt
Zeichen 8 signed −128 bis 127
unsigned 0 bis 255
16 UTF-16 0 bis 65535
32 UTF-32 0 bis 1114111 (0x10ffff)
Ganzzahl 16 signed ± 3,27 · 104 −32768 bis 32767
unsigned 0 bis 6,55 · 104 0 bis 65535
32 signed ± 2,14 · 109 −2.147.483.648 bis 2.147.483.647
unsigned 0 bis 4,29 · 109 0 bis 4.294.967.295
64 signed ± 9,22 · 1018 −9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807
unsigned 0 bis 1,84 · 1019 0 bis 18.446.744.073.709.551.615
binary
Gleitkomma-
zahl
32 IEEE-754
  • min. Subnormal
    ± 1,401.298.4 · 10−45
  • min. Normal
    ± 1,175.494.3 · 10−38
  • max
    ± 3,402.823.4 · 1038
  • min. Subnormal
    ±0x1p−149
  • min. Normal
    ±0x1p−126
  • max
    ±0x1.fffffep+127
64 IEEE-754
  • min. Subnormal
    ± 4,940.656.458.412 · 10−324
  • min. Normal
    ± 2,225.073.858.507.201,4 · 10−308
  • max
    ± 1,797.693.134.862.315,7 · 10308
  • min. Subnormal
    ±0x1p−1074
  • min. Normal
    ±0x1p−1022
  • max
    ±0x1.fffffffffffffp+1023
80[Anmerkung 1] x86
  • min. Subnormal
    ± 3,645.199.531.882.474.602.528
     · 10−4951
  • min. Normal
    ± 3,362.103.143.112.093.506.263
     · 10−4932
  • max
    ± 1,189.731.495.357.231.765.021
     · 104932
  • min. Subnormal
    ±0x1p−16445
  • min. Normal
    ±0x1p−16382
  • max
    ±0x1.fffffffffffffffep+16383
128 IEEE-754
  • min. Subnormal
    ± 6,475.175.119.438.025.110.924,
    438.958.227.646.552,5 · 10−4966
  • min. Normal
    ± 3,362.103.143.112.093.506.262,
    677.817.321.752.602,6 · 10−4932
  • max
    ± 1,189.731.495.357.231.765.085,
    759.326.628.007.016,2 · 104932
  • min. Subnormal
    ±0x1p−16494
  • min. Normal
    ±0x1p−16382
  • max
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
dezimal
Gleitkomma-
zahl
32 IEEE-754
  • min. Subnormal
    ± 1 · 10-101
  • min. Normal
    ± 1 · 10-95
  • max
    ± 9,999'999 · 1096
64 IEEE-754
  • min. Subnormal
    ± 1 · 10-398
  • min. Normal
    ± 1 · 10-383
  • max
    ± 9,999'999'999'999'999 · 10384
128 IEEE-754
  • min. Subnormal
    ± 1 · 10-6176
  • min. Normal
    ± 1 · 10-6143
  • max
    ± 9,999'999'999'999'999'999'
    999'999'999'999'999 · 106144
  1. Die Objekt-Repräsentation belegt normalerweise 96/128 Bits auf 32/64-Bit-Plattformen.

Hinweis: Die tatsächlichen (im Gegensatz zu den garantierten minimalen) Bereiche sind in den Header-Dateien <limits.h> und <float.h> verfügbar.

[bearbeiten] Siehe auch

C++ Dokumentation für Fundamentale Typen