Stockage des données du langage C (entier et virgule flottante) en mémoire

Table des matières

1. Classification de base des types

1.1 Entier

1.2 Virgule flottante

1.3 Type de construction

1.4 Types de pointeurs

1.5 Types vides

2. Stockage des entiers en mémoire

2.1 Nombres de machines et valeurs de vérité

2.1.1 Nombre de machines

2.1.2 Valeur de vérité

2.2 Complément et inverse du code original

2.2.1 Code d'origine

2.2.2 Code inverse

2.2.3 Code complémentaire

2.2.4 Forme de stockage des données entières

2.3 Introduction au grand et au petit endian

2.3.1 Qu'est-ce que le big endian et le little endian

2.3.2 Pourquoi il existe un mode grand et petit endian

2.3.3 Les avantages respectifs du stockage big et small endian

3. Stockage des nombres à virgule flottante en mémoire

3.1 Exemples de stockage à virgule flottante

3.2 Règles de stockage des nombres à virgule flottante

3.2.1 Représentation binaire et conversion décimale de nombres à virgule flottante

3.2.2 Réglementations IEEE 754

3.2.3 Règlements spéciaux de l'IEEE 754 sur les chiffres significatifs M et l'exposant E :


1. Classification de base des types

1.1 Entier

char
        non signé char
        signé char
court
        non signé court [int]
        signé court [int]
int
        non signé int
        signé int
long
        non signé long [int]
        signé long [int]

1.2 Virgule flottante

flotteur
double

1.3 Type de construction

> Type de tableau
> Type de structure struct
> Type d'énumération >
Union de type joint

1.4 Types de pointeurs

int * pi;
char * pc ;
float* pf;
vide* pv;

1.5 Types vides

void signifie un type vide (pas de type)
généralement appliqué au type de retour de fonction, au paramètre de fonction, au type de pointeur.

2. Stockage des entiers en mémoire

Nous savons que créer une variable, c'est ouvrir de l'espace en mémoire, et la taille de l'espace ouvert varie selon les types. Si vous voulez savoir comment la stocker, vous devez d'abord connaître les concepts suivants.

2.1 Nombres de machines et valeurs de vérité

2.1.1 Nombre de machines

La représentation binaire d'un nombre dans un ordinateur est appelée le numéro machine du nombre. Le numéro de machine est signé et le bit le plus élevé d'un nombre est utilisé pour stocker le signe dans l'ordinateur, le nombre positif est 0 et le nombre négatif est 1.

Par exemple, le nombre en décimal + 2, la longueur du mot informatique est de 8 bits, converti en binaire est 00000010. Si c'est -2, c'est 10000010.

Ensuite, 00000011 et 10000011, voici les numéros de machine.

2.1.2 Valeur de vérité

Étant donné que le premier bit du numéro de machine est le bit de signe, le numéro de machine n'est pas égal à la valeur réelle. Par exemple, dans le nombre signé ci-dessus 10000010, le bit le plus élevé 1 représente négatif et sa valeur réelle est -2 au lieu de la valeur formelle 130 (10000011 converti en décimal est égal à 130). Ainsi, par souci de distinction, la valeur réelle correspondant au numéro de machine avec le bit signé est appelée valeur réelle du numéro de machine.

2.2 Complément et inverse du code original

Il existe trois méthodes de représentation binaire des entiers dans les ordinateurs, à savoir le code original, le code complément et le code complément (trois formes de nombres machines).
Les trois méthodes de représentation comportent toutes deux parties, le bit de signe et le bit de valeur. Le bit de signe utilise 0 pour représenter "positif" et 1 pour représenter "négatif"
. Il existe trois manières différentes de représenter des entiers négatifs.

2.2.1 Code d'origine

Le code original est la valeur absolue du bit de signe plus la vraie valeur , c'est-à-dire que le premier bit est utilisé pour représenter le signe et les bits restants représentent la valeur. Par exemple, s'il s'agit d'un binaire de 8 bits :

  • Le code original de +1 : [0 (bit de signe)]+[000 0001 (bit de valeur)]=0000 0001 ;
  • Le code source de -1 : [1 (bit de signe)]+[000 0001 (bit de valeur)]=1000 0001 ;

2.2.2 Code inverse

Le complément à un d’un nombre positif est lui-même ; le complément à un d’un nombre négatif s’obtient en inversant les autres bits sur la base de son code d’origine sans changer le bit de signe.

  • [+1] = [0000 0001] original = [0000 0001] anti
  • [ -1] = [1000 0001] original = [1111 1110] anti

2.2.3 Code complémentaire

Le complément d'un nombre positif est lui-même ; le complément d'un nombre négatif est basé sur le code original, le bit de signe reste inchangé, le reste des bits est inversé et enfin +1. (C'est-à-dire +1 sur la base du code inverse)

  • [+1] = [0000 0001] original = [0000 0001] inverse = [0000 0001] complément
  • [-1] = [1000 0001] original = [1111 1110] inverse = [1111 1111] complément

2.2.4 Forme de stockage des données entières

Les données entières sont stockées en mémoire sous forme de code complémentaire. La raison est la suivante : en utilisant le code complémentaire, le bit de signe et le champ de valeur peuvent être traités de manière uniforme ; en même temps, l'addition et la soustraction peuvent également être traitées de manière uniforme (la CPU n'a qu'un additionneur). De plus, le processus de fonctionnement de le code complémentaire et le code original sont les mêmes. Des circuits matériels supplémentaires sont requis.

 D'après la figure ci-dessus, nous savons que tous les compléments sont stockés dans la mémoire, mais pourquoi sont-ils dans l'ordre de l'arrière vers l'avant ?C'est parce qu'il existe une forme de stockage grand et petit endian. La prochaine étape consiste à introduire le stockage big et small endian.

2.3 Introduction au grand et au petit endian

2.3.1 Qu'est-ce que le big endian et le little endian

Le mode big-endian (stockage) signifie que les bits de données faibles sont stockés dans les adresses hautes de la mémoire, tandis que les bits de données hauts sont stockés dans les adresses basses de la mémoire
;
le
mode small-endian (stockage) signifie que les bits de données faibles sont stockés à l'adresse basse, tandis que les bits de poids fort des données sont stockés à l'
adresse haute de la mémoire.

Dans cette image, les bits faibles typiques sont stockés dans l'adresse basse de la mémoire, et les bits forts des données sont stockés dans l'adresse haute de la mémoire (mode de stockage Little Endian).

2.3.2 Pourquoi il existe un mode grand et petit endian

Pourquoi y a-t-il une différence entre les modes grand et petit endian ? En effet, dans le système informatique, nous utilisons les octets comme unité, et chaque unité d'adresse
correspond à un octet, et un octet est composé de 8 bits. Mais dans le langage C, en plus des caractères 8 bits, il existe également
des types courts 16 bits et des types longs 32 bits (selon le compilateur spécifique). De plus, pour les processeurs de plus de 8 bits, comme 16 bits Ou un
processeur 32 bits, puisque la largeur du registre est supérieure à un octet, il doit y avoir un problème sur la façon d'organiser plusieurs octets. Par conséquent
, cela conduit au mode de stockage big-endian et au mode de stockage small-endian.
Par exemple : un type court de 16 bits x, l'adresse dans la mémoire est 0x0010, la valeur de x est 0x1122, puis 0x11 est l'
octet de poids fort et 0x22 est l'octet de poids faible. Pour le mode big-endian, mettez 0x11 dans l'adresse basse, c'est-à-dire 0x0010, et mettez 0x22 dans l'
adresse haute, c'est-à-dire 0x0011. Le mode Little Endian, c'est tout le contraire. Notre structure X86 couramment utilisée est le mode petit-boutiste, tandis que KEIL C51
est le mode gros-boutiste. De nombreux ARM et DSP sont en mode petit-boutiste.
Certains processeurs ARM peuvent également choisir le mode big-endian ou le mode small-endian par matériel .

2.3.3 Les avantages respectifs du stockage big et small endian

Avantages du mode petit endian :

  • L'adresse basse de la mémoire stocke l'octet faible, il n'est donc pas nécessaire d'ajuster le contenu de l'octet lors de la conversion des données (Remarque : par exemple, lors de la conversion de 4 octets de int en 2 octets de short, les données int sont stockées directement Donnez simplement les deux premiers octets à court, car les deux premiers octets ne sont que les deux octets les plus bas, ce qui est conforme à la logique de conversion);
  • Lorsque le processeur effectue des calculs numériques, il récupère les données de la mémoire de bas en haut pour le calcul jusqu'à ce que le bit de signe le plus élevé soit actualisé à la fin. Cette méthode de fonctionnement sera plus efficace.

Avantages du mode big endian :

  • Le bit de signe se trouve dans le premier octet de la mémoire des données représentées, ce qui est pratique pour juger rapidement le positif et le négatif ainsi que la taille des données.
  • Leurs avantages respectifs sont les inconvénients l'un de l'autre. Parce que les deux sont égaux, couplés à l'insistance de certains fabricants de matériel, il n'existe jamais de norme unifiée pour l'ordre de stockage multi-octets.

3. Stockage des nombres à virgule flottante en mémoire

3.1 Exemples de stockage à virgule flottante

int main()
{
    int n = 9;
    float *pFloat = (float *)&n;
    printf("n的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);

    *pFloat = 9.0;
    printf("num的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);
    return 0;
}

Et le résultat de l'exécution de ce code est :

 

 Mais pourquoi y a-t-il un si grand écart entre les résultats de l'interprétation des nombres entiers et des nombres à virgule flottante du même nombre, alors nous devons comprendre les règles de stockage des nombres à virgule flottante.

3.2 Règles de stockage des nombres à virgule flottante

3.2.1 Représentation binaire et conversion décimale de nombres à virgule flottante

 3.2.2 Réglementations IEEE 754

Selon la norme internationale IEEE (Institute of Electrical and Electronics Engineering) 754, tout nombre binaire à virgule flottante V peut être exprimé sous la forme suivante :

  • (-1)^S * M * 2^E
  • (-1)^S représente le bit de signe, lorsque S=0, V est un nombre positif ; lorsque S=1, V est un nombre négatif.
  • M représente un nombre valide, supérieur ou égal à 1 et inférieur à 2.
  • 2 ^ E signifie bits d'exposant.
     

 Par exemple:

  • 5,0 en décimal équivaut à 101,0 en binaire, ce qui équivaut à 1,01×2^2.
  • Ensuite, selon le format de V ci-dessus, on peut conclure que S=0, M=1,01 et E=2.
  • Le décimal -5,0, écrit en binaire est -101,0, ce qui équivaut à -1,01×2^2. Alors, S=1, M=1,01, E=2.

Modèle de stockage de nombres à virgule flottante : 

 (1) Pour les nombres à virgule flottante de 32 bits, le bit le plus élevé est le bit de signe s, les 8 bits suivants sont l'exposant E et les 23 bits restants sont le nombre effectif M.

 (2) Pour les nombres à virgule flottante de 64 bits, le bit le plus élevé est le bit de signe S, les 11 bits suivants sont l'exposant E et les 52 bits restants sont le nombre effectif M.

3.2.3 Règlements spéciaux de l'IEEE 754 sur les chiffres significatifs M et l'exposant E :

1. Règlements particuliers pour le numéro effectif M :

Comme mentionné précédemment, 1≤M<2, c'est-à-dire que M peut s'écrire sous la forme 1.xxxxxx, où xxxxxx représente la partie décimale.
IEEE 754 stipule que lorsque M est enregistré dans l'ordinateur, le premier chiffre de ce numéro est toujours 1 par défaut, il peut donc être supprimé et seule la partie xxxxxx suivante est enregistrée. Par exemple, lors de la sauvegarde de 1.01, enregistrez uniquement 01, puis ajoutez le premier 1 lors de la lecture. Le but de cette opération est d’économiser 1 chiffre significatif. En prenant comme exemple le nombre à virgule flottante de 32 bits, il ne reste que 23 bits pour M. Une fois le premier 1 supprimé, cela équivaut à enregistrer 24 chiffres significatifs.

2. Dispositions particulières pour l'Indice E :

1.1 Règlements sur les nombres intermédiaires (afin de distinguer les exposants positifs et négatifs)

Premièrement, E est un entier non signé (unsigned int), ce qui signifie que si E est de 8 bits, sa plage de valeurs est de 0 à 255 ; si E est de 11 bits, sa plage de valeurs est de 0 à 2 047. Cependant, nous savons que E en notation scientifique peut avoir des nombres négatifs, c'est pourquoi la norme IEEE 754 stipule qu'un nombre intermédiaire doit être ajouté à la valeur réelle de E lorsqu'il est stocké en mémoire. Pour un E 8 bits, ce nombre intermédiaire est 127 ; pour 11 -bit E, ce nombre intermédiaire est 1023 . Par exemple, le E de 2^10 est 10, donc lorsque vous l'enregistrez sous forme de nombre à virgule flottante de 32 bits, il doit être enregistré sous 10+127=137, soit 10001001.

1.2 E n'est pas tout à 0 ou tout à fait à 1

À ce stade, le nombre à virgule flottante est représenté par les règles suivantes, c'est-à-dire que la valeur calculée de l'exposant E est soustraite de 127 (ou 1023) pour obtenir la valeur réelle, puis le premier chiffre 1 est ajouté avant
le nombre effectif M.
Par exemple :
 la forme binaire de 0,5 (1/2) est 0,1. Puisque la partie positive doit être 1, c'est-à-dire que le point décimal est décalé de 1 bit vers la droite, alors c'est 1,0*2^(-1
) , et son code de commande est -1+127= 126, exprimé par 01111110, et la mantisse 1.0 supprime la partie entière pour être 0 et remplit 0 à 23 chiffres 0000000000000000000000000, alors sa représentation binaire est :

0 01111110 00000000000000000000000

1,3 E est tout 0

A ce moment, l'exposant E du nombre à virgule flottante égal à 1-127 (ou 1-1023) est la valeur réelle, et le nombre effectif M n'est plus additionné avec le premier chiffre de 1, mais est restitué à un décimal de 0,xxxxxx. Ceci est fait pour représenter ±0 et de très petits nombres proches de 0.

1,4 E est tout 1

A ce moment, si le nombre significatif M est entièrement 0, cela signifie ± l'infini (positif ou négatif dépend du bit de signe s) ;
 

Enfin : le texte du code n'est pas facile, demandez trois liens en un clic.

Je suppose que tu aimes

Origine blog.csdn.net/qq_64293926/article/details/127351107
conseillé
Classement