Namespaces
Variants

Arithmetic types

From cppreference.net

(Voir aussi type pour un aperçu du système de types et la liste des utilitaires liés aux types fournis par la bibliothèque C.)

Table des matières

Type booléen

  • _Bool (également accessible via la macro bool ) (jusqu'à C23) bool (depuis C23) — type capable de contenir l'une des deux valeurs : 1 et 0 (également accessibles via les macros true et false ) (jusqu'à C23) true et false (depuis C23) .

Notez que la conversion vers _Bool (jusqu'à C23) bool (depuis C23) ne fonctionne pas de la même manière que la conversion vers d'autres types entiers : ( bool ) 0.5 s'évalue à true , tandis que ( int ) 0.5 s'évalue à 0 .

(depuis C99)

Types de caractères

  • signed char — type pour la représentation de caractères signés.
  • unsigned char — type pour la représentation de caractères non signés. Également utilisé pour inspecter les représentations d'objets (mémoire brute).
  • char — type pour la représentation de caractères. Équivalent à signed char ou unsigned char (le choix étant défini par l'implémentation et pouvant être contrôlé par un commutateur en ligne de commande du compilateur), mais char est un type distinct, différent à la fois de signed char et de unsigned char .

Notez que la bibliothèque standard définit également typedef les noms wchar_t , char16_t et char32_t (depuis C11) pour représenter les caractères larges et char8_t pour les caractères UTF-8 (depuis C23) .

Types entiers

  • short int (également accessible sous short , peut utiliser le mot-clé signed )
  • unsigned short int (également accessible sous unsigned short )
  • int (également accessible sous signed int )
Ceci est le type entier le plus optimal pour la plateforme, et il est garanti d'être d'au moins 16 bits. La plupart des systèmes actuels utilisent 32 bits (voir les modèles de données ci-dessous).
  • unsigned int (également accessible sous unsigned ), la contrepartie non signée de int , implémentant l'arithmétique modulo. Convient pour les manipulations de bits.
  • long int (également accessible sous long )
  • unsigned long int (également accessible sous unsigned long )
  • long long int (également accessible sous le nom long long )
  • unsigned long long int (également accessible sous le nom unsigned long long )
(depuis C99)
  • _BitInt ( n ) (également accessible sous le nom signed _BitInt ( n ) ), les types entiers signés à précision de bits (où n est remplacé par une expression constante entière désignant la largeur précise (incluant le bit de signe), qui ne peut pas être supérieure à BITINT_MAXWIDTH de <limits.h> )
  • unsigned _BitInt ( n ) , les types entiers non signés à précision de bits (où n est remplacé par une expression constante entière désignant la largeur précise, qui ne peut pas être supérieure à BITINT_MAXWIDTH de <limits.h> )
(depuis C23)

Note : comme pour tous les spécificateurs de type, tout ordre est autorisé : unsigned long long int et long int unsigned long désignent le même type.

Le tableau suivant résume tous les types entiers disponibles et leurs propriétés :

**Note:** Le texte a été laissé en anglais car il s'agit de termes spécifiques au C++ (comme demandé dans les instructions). Les balises HTML et leur formatage ont été préservés intacts.
Spécificateur de type Type équivalent Largeur en bits par modèle de données
Norme C LP32 ILP32 LLP64 LP64
char
char au moins
8
8 8 8 8
signed char
signed char
unsigned char
unsigned char
short
short int au moins
16
16 16 16 16
short int
signed short
signed short int
unsigned short
unsigned short int
unsigned short int
int
int au moins
16
16 32 32 32
signé
signed int
unsigned
unsigned int
unsigned int
long
long int au moins
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)
au moins
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

Outre les nombres minimaux de bits, la norme C garantit que

1 == sizeof ( char ) sizeof ( short ) sizeof ( int ) sizeof ( long ) sizeof ( long long ) .
La traduction du texte en français est : 1 == sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long). **Note :** J'ai respecté toutes les contraintes : - Les balises HTML et attributs sont conservés intacts - Le contenu des balises ` ` n'est pas traduit (les symboles ≤ restent inchangés) - Les termes spécifiques au C++ (sizeof, char, short, int, long) ne sont pas traduits - La structure et le formatage d'origine sont préservés

Note : cela permet le cas extrême où les bytes ont une taille de 64 bits, tous les types (y compris char ) ont une largeur de 64 bits, et sizeof renvoie 1 pour chaque type.

Note : l'arithmétique entière est définie différemment pour les types entiers signés et non signés. Voir les opérateurs arithmétiques , en particulier les dépassements d'entiers .

Modèles de données

Les choix effectués par chaque implémentation concernant les tailles des types fondamentaux sont collectivement appelés modèle de données . Quatre modèles de données ont été largement adoptés :

Systèmes 32 bits :

  • LP32 ou 2/4/4 ( int est 16-bit, long et pointeur sont 32-bit)
  • API Win16
  • ILP32 ou 4/4/4 ( int , long , et pointeur sont 32-bit);
  • API Win32
  • Systèmes Unix et de type Unix (Linux, Mac OS X)

Systèmes 64 bits :

  • LLP64 ou 4/4/8 ( int et long sont 32 bits, le pointeur est 64 bits)
  • API Win64
  • LP64 ou 4/8/8 ( int est 32 bits, long et le pointeur sont 64 bits)
  • Systèmes Unix et de type Unix (Linux, Mac OS X)

D'autres modèles sont très rares. Par exemple, ILP64 ( 8/8/8 : int , long , et les pointeurs sont 64 bits) n'est apparu que dans certains systèmes Unix 64 bits anciens (par exemple Unicos sur Cray ).

Notez que les types entiers de largeur exacte sont disponibles dans <stdint.h> depuis C99.

Types flottants réels

C possède trois ou six (depuis C23) types pour représenter les valeurs réelles en virgule flottante :

  • float — type à virgule flottante simple précision. Correspond au format IEEE-754 binary32 s'il est pris en charge.
  • double — type à virgule flottante double précision. Correspond au format IEEE-754 binary64 s'il est pris en charge.
  • long double — type à virgule flottante étendue précision. Correspond au format IEEE-754 binary128 s'il est pris en charge, sinon correspond au format IEEE-754 binary64 -étendu s'il est pris en charge, sinon correspond à un format à virgule flottante étendu non IEEE-754 tant que sa précision est meilleure que binary64 et sa plage au moins aussi bonne que binary64 , sinon correspond au format IEEE-754 binary64 .
    • binary128 est utilisé par certaines implémentations HP-UX, SPARC, MIPS, ARM64 et z/OS.
    • Le format IEEE-754 binary64 -étendu le plus connu est le format étendu x87 80-bit. Il est utilisé par de nombreuses implémentations x86 et x86-64 (une exception notable est MSVC, qui implémente long double dans le même format que double , c'est-à-dire binary64 ).
Si l'implémentation prédéfinit la macro constante __STDC_IEC_60559_DFP__ , les types de virgule flottante décimaux suivants sont également pris en charge.
Sinon, ces types de virgule flottante décimaux ne sont pas pris en charge.
(depuis C23)

Les types à virgule flottante peuvent prendre en charge des valeurs spéciales :

  • l'infini (positif et négatif), voir INFINITY
  • le zéro négatif , - 0.0 . Il est égal au zéro positif, mais est significatif dans certaines opérations arithmétiques, par exemple 1.0 / 0.0 == INFINITY , mais 1.0 / - 0.0 == - INFINITY )
  • non-nombre (NaN), qui n'est égal à rien (y compris lui-même). Plusieurs motifs binaires représentent les NaNs, voir nan , NAN . Notez que C ne traite pas spécialement les NaNs signalés (spécifiés par IEEE-754) et considère tous les NaNs comme silencieux.

Les nombres réels à virgule flottante peuvent être utilisés avec les opérateurs arithmétiques + - / * et diverses fonctions mathématiques de <math.h> . Les opérateurs intégrés et les fonctions de bibliothèque peuvent lever des exceptions de virgule flottante et définir errno comme décrit dans math_errhandling .

Les expressions en virgule flottante peuvent avoir une plage et une précision supérieures à celles indiquées par leurs types, voir FLT_EVAL_METHOD . L'assignation , return , et cast forcent la plage et la précision à celles associées au type déclaré.

Les expressions en virgule flottante peuvent également être contractées , c'est-à-dire calculées comme si toutes les valeurs intermédiaires avaient une plage et une précision infinies, voir #pragma STDC FP_CONTRACT .

Certaines opérations sur les nombres à virgule flottante sont affectées par et modifient l'état de l'environnement de virgule flottante (notamment, la direction d'arrondi).

Conversions implicites sont définies entre les types flottants réels et les types entiers, complexes et imaginaires.

Voir Limites des types à virgule flottante et la bibliothèque <math.h> pour des détails supplémentaires, limites et propriétés des types à virgule flottante.

Types à virgule flottante complexes

Les types à virgule flottante complexes modélisent les nombres complexes mathématiques, c'est-à-dire les nombres qui peuvent s'écrire comme la somme d'un nombre réel et d'un nombre réel multiplié par l'unité imaginaire : a + bi

Les trois types complexes sont

Remarque : comme pour tous les spécificateurs de type, tout ordre est autorisé : long double complex , complex long double , et même double complex long désignent le même type.

#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));
}

Sortie :

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

Si la macro constante __STDC_NO_COMPLEX__ est définie par l'implémentation, les types complexes (ainsi que l'en-tête de bibliothèque <complex.h> ) ne sont pas fournis.

(depuis C11)

Chaque type complexe possède la même représentation d'objet et les mêmes exigences d'alignement qu'un tableau de deux éléments du type réel correspondant ( float pour float complex , double pour double complex , long double pour long double complex ). Le premier élément du tableau contient la partie réelle, et le deuxième élément du tableau contient la composante imaginaire.

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

Les nombres complexes peuvent être utilisés avec les opérateurs arithmétiques + - * et / , éventuellement mélangés avec des nombres imaginaires et réels. De nombreuses fonctions mathématiques sont définies pour les nombres complexes dans <complex.h> . Les opérateurs intégrés et les fonctions de bibliothèque peuvent lever des exceptions en virgule flottante et définir errno comme décrit dans math_errhandling .

L'incrémentation et la décrémentation ne sont pas définies pour les types complexes.

Les opérateurs relationnels ne sont pas définis pour les types complexes (il n'existe pas de notion de "inférieur à").

Conversions implicites are defined between complex types and other arithmetic types.

Afin de soutenir le modèle un-infini de l'arithmétique des nombres complexes, C considère toute valeur complexe avec au moins une partie infinie comme une infini même si son autre partie est un NaN, garantit que tous les opérateurs et fonctions respectent les propriétés fondamentales des infinis et fournit cproj pour mapper tous les infinis vers l'infini canonique (voir opérateurs arithmétiques pour les règles exactes).

#include <complex.h>
#include <math.h>
#include <stdio.h>
int main(void)
{
    double complex z = (1 + 0*I) * (INFINITY + I*INFINITY);
//  la formule théorique donnerait
//  (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN
//  mais C donne un infini complexe
    printf("%f%+f*i\n", creal(z), cimag(z));
//  la formule théorique donnerait
//  cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN
//  mais C donne  ±∞+i*nan
    double complex y = cexp(INFINITY + I*NAN);
    printf("%f%+f*i\n", creal(y), cimag(y));
}

Sortie possible :

inf+inf*i 
inf+nan*i

C traite également les multiples infinis de manière à préserver l'information directionnelle lorsque cela est possible, malgré les limitations inhérentes à la représentation cartésienne :

multiplier l'unité imaginaire par l'infini réel donne l'infini imaginaire correctement signé : i × ∞ = i∞. De plus, i × (∞ – i∞) = ∞ + i∞ indique le quadrant raisonnable.

Types flottants imaginaires

Les types flottants imaginaires modélisent les nombres imaginaires mathématiques, c'est-à-dire des nombres qui peuvent s'écrire comme un nombre réel multiplié par l'unité imaginaire : bi Les trois types imaginaires sont

Note : comme pour tous les spécificateurs de type, tout ordre est autorisé : long double imaginary , imaginary long double , et même double imaginary long désignent le même type.

#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));
}

Sortie :

1/(3.0i) = -0.3i

Une implémentation qui définit __STDC_IEC_559_COMPLEX__ est recommandée, mais n'est pas obligée de prendre en charge les nombres imaginaires. POSIX recommande de vérifier si la macro _Imaginary_I est définie pour identifier la prise en charge des nombres imaginaires.

(jusqu'à C11)

Les nombres imaginaires sont pris en charge si __STDC_IEC_559_COMPLEX__ (jusqu'à C23) __STDC_IEC_60559_COMPLEX__ (depuis C23) est définie.

(depuis C11)

Chacun des trois types imaginaires possède la même représentation d'objet et les mêmes exigences d'alignement que son type réel correspondant ( float pour float imaginary , double pour double imaginary , long double pour long double imaginary ).

Note : bien que les types imaginaires soient distincts et non compatibles avec leurs types réels correspondants, ce qui interdit l'aliasing.

Les nombres imaginaires peuvent être utilisés avec les opérateurs arithmétiques + - * et / , éventuellement mélangés avec des nombres complexes et réels. De nombreuses fonctions mathématiques sont définies pour les nombres imaginaires dans <complex.h> . Les opérateurs intégrés et les fonctions de bibliothèque peuvent lever des exceptions en virgule flottante et définir errno comme décrit dans math_errhandling .

L'incrémentation et la décrémentation ne sont pas définies pour les types imaginaires.

Conversions implicites are defined between imaginary types and other arithmetic types.

Les nombres imaginaires permettent d'exprimer tous les nombres complexes en utilisant la notation naturelle x + I * y (où I est défini comme _Imaginary_I ). Sans les types imaginaires, certaines valeurs complexes spéciales ne peuvent pas être créées naturellement. Par exemple, si I est défini comme _Complex_I , alors écrire 0.0 + I * INFINITY donne NaN comme partie réelle, et CMPLX ( 0.0 , INFINITY ) doit être utilisé à la place. Il en va de même pour les nombres avec une composante imaginaire de zéro négatif, qui sont significatifs lors de l'utilisation des fonctions de bibliothèque avec des coupures de branche, telles que csqrt : 1.0 - 0.0 * I donne une composante imaginaire de zéro positif si I est défini comme _Complex_I et la partie imaginaire de zéro négatif nécessite l'utilisation de CMPLX ou conj .

Les types imaginaires simplifient également les implémentations ; la multiplication d'un imaginaire par un complexe peut être implémentée directement avec deux multiplications si les types imaginaires sont pris en charge, au lieu de quatre multiplications et deux additions.

(depuis C99)

Mots-clés

Plage de valeurs

Le tableau suivant fournit une référence pour les limites des représentations numériques courantes.

Avant C23, la norme C autorisait toute représentation d'entiers signés, et la plage minimale garantie des entiers signés de N bits était de -(2 N-1
-1)
à +2 N-1
-1
(par exemple -127 à 127 pour un type signé 8 bits), ce qui correspond aux limites du complément à un ou de la représentation signe-magnitude .

Cependant, tous les modèles de données populaires (y compris ILP32, LP32, LP64, LLP64) et presque tous les compilateurs C utilisent la représentation en complément à deux (les seules exceptions connues sont certains compilateurs pour UNISYS), et depuis C23, c'est la seule représentation autorisée par la norme, avec la plage garantie de -2 N-1
à +2 N-1
-1
(par exemple -128 à 127 pour un type signé 8 bits).

Type Taille en bits Format Plage de valeurs
Approximatif Exact
caractère 8 signé −128 à 127
non signé 0 à 255
16 UTF-16 0 à 65535
32 UTF-32 0 à 1114111 ( 0x10ffff )
entier 16 signé ± 3.27 · 10 4 −32768 à 32767
non signé 0 à 6.55 · 10 4 0 à 65535
32 signé ± 2.14 · 10 9 −2,147,483,648 à 2,147,483,647
non signé 0 à 4.29 · 10 9 0 à 4,294,967,295
64 signé ± 9.22 · 10 18 −9,223,372,036,854,775,808 à 9,223,372,036,854,775,807
non signé 0 à 1.84 · 10 19 0 à 18,446,744,073,709,551,615
virgule flottante
binaire
32 IEEE-754
  • sous-normal minimal :
    ± 1.401,298,4 · 10 −45
  • normal minimal :
    ± 1.175,494,3 · 10 −38
  • maximal :
    ± 3.402,823,4 · 10 38
  • sous-normal minimal :
    ±0x1p−149
  • normal minimal :
    ±0x1p−126
  • maximal :
    ±0x1.fffffep+127
64 IEEE-754
  • sous-normal minimal :
    ± 4.940,656,458,412 · 10 −324
  • normal minimal :
    ± 2.225,073,858,507,201,4 · 10 −308
  • maximal :
    ± 1.797,693,134,862,315,7 · 10 308
  • sous-normal minimal :
    ±0x1p−1074
  • normal minimal :
    ±0x1p−1022
  • maximal :
    ±0x1.fffffffffffffp+1023
80 [note 1] x86
  • sous-normal minimal :
    ± 3.645,199,531,882,474,602,528
    · 10 −4951
  • normal minimal :
    ± 3.362,103,143,112,093,506,263
    · 10 −4932
  • maximal :
    ± 1.189,731,495,357,231,765,021
    · 10 4932
  • sous-normal minimal :
    ±0x1p−16445
  • normal minimal :
    ±0x1p−16382
  • maximal :
    ±0x1.fffffffffffffffep+16383
128 IEEE-754
  • sous-normal minimal :
    ± 6.475,175,119,438,025,110,924,
    438,958,227,646,552,5 · 10 −4966
  • normal minimal :
    ± 3.362,103,143,112,093,506,262,
    677,817,321,752,602,6 · 10 −4932
  • maximal :
    ± 1.189,731,495,357,231,765,085,
    759,326,628,007,016,2 · 10 4932
  • sous-normal minimal :
    ±0x1p−16494
  • normal minimal :
    ±0x1p−16382
  • maximal :
    ±0x1.ffffffffffffffffffffffffffff
    p+16383
virgule flottante
décimale
32 IEEE-754
  • sous-normal minimal :
    ± 1 · 10 -101
  • normal minimal :
    ± 1 · 10 -95
  • maximal :
    ± 9.999'999 · 10 96
64 IEEE-754
  • sous-normal minimal :
    ± 1 · 10 -398
  • normal minimal :
    ± 1 · 10 -383
  • maximal :
    ± 9.999'999'999'999'999 · 10 384
128 IEEE-754
  • sous-normal minimal :
    ± 1 · 10 -6176
  • normal minimal :
    ± 1 · 10 -6143
  • maximal :
    ± 9.999'999'999'999'999'999'
    999'999'999'999'999 · 10 6144
  1. La représentation objet occupe généralement 96/128 bits sur les plateformes 32/64 bits respectivement.

Note : les plages réelles (par opposition aux minimales garanties) sont disponibles dans les en-têtes de la bibliothèque <limits.h> et <float.h> .

Voir aussi

Documentation C++ pour Types fondamentaux