[C] Stockage des données en mémoire

avant-propos

> Dans la mémoire, la manière de stocker entier et virgule flottante est différente, et la manière de lire depuis la mémoire est également différente.Cet article présente principalement la manière de stocker entier et virgule flottante en mémoire.

Stockage d'entiers en mémoire

Il existe trois représentations des nombres signés dans les ordinateurs :

  1. Code original : il suffit de traduire le binaire en binaire sous la forme de nombres positifs et négatifs.
  2. Code inverse : le bit de signe du code d'origine reste inchangé, et le code d'origine peut être inversé bit par bit. (Le bit binaire le plus élevé est le bit de signe, 0 est positif, 1 est négatif)
  3. Code complémentaire : code inverse plus un pour obtenir le code complémentaire.

Le code d'origine, le code inverse et le code complémentaire des nombres positifs sont les mêmes.
Par exemple :
1 est complément à un complément

Code original : 00000000 00000000 00000000 00000001
Code inverse : 00000000 00000000 00000000 00000001
Code complémentaire : 00000000 00000000 00000000 00000001

Le complément du code original de -1

Code original : 10000000 00000000 000000000001 00000001 Code tige
: 1111111111 111111111111111 1111111111
Code complément : 11111111111111111111111 11111111 11

Les entiers sont également divisés en entiers signés et entiers non signés. Les entiers non signés n'ont pas de bit de signe et les 32 bits sont des bits valides, donc les entiers non signés sont tous supérieurs ou égaux à 0.
Les entiers sont stockés en complément à deux en mémoire. Pourquoi dites vous cela?
Dans les systèmes informatiques, les valeurs sont toujours exprimées et stockées en complément à deux. La raison en est qu'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 d'opération du code complémentaire et du code d'origine est le même, aucun circuit matériel supplémentaire n'est requis.

Stockage gros et petit endian

Mode big-endian (stockage) : Cela signifie que les bits de poids faible des données sont stockés dans les adresses hautes de la mémoire, et les bits de poids fort des données sont stockés dans les adresses basses de la mémoire.
Mode Little Endian (stockage) : cela signifie que les bits de poids faible des données sont stockés dans les adresses basses de la mémoire, tandis que les bits de poids fort des données sont stockés dans les adresses hautes de la mémoire.

Alors, comment concevoir un programme pour juger si la machine est un stockage à gros segments ou un stockage petit-boutiste ?

Nous pouvons utiliser le chiffre 1 comme exemple. Nous retirons l'adresse de a et la forçons dans un pointeur de caractère, de sorte que nous ne pouvons accéder qu'au contenu d'un octet lors du déréférencement. Si le contenu de cet octet est 1, cela prouve que la machine est un stockage little endian, sinon un stockage big-endian.
code afficher comme ci-dessous:

#include <stdio.h>

int main()
{
    
    
	int x = 1;
	if (*(char*)&x == 1)
	{
    
    
		printf("小端存储\n");
	}
	else
	{
    
    
		printf("大端存储\n");
	}
	return 0;
}

Stockage des types à virgule flottante en mémoire

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 bit d'exposant

Par exemple :
Le binaire de 5,5 est : (-1)^0 * 1,011 * 2^2 Ici S=0 ; M=1,011 ; E=2 ; Le binaire de -5,5 est : (-1)^1 * 1,011 * 2^
2 Ici S=1 ; M=1,011 ; E=2 ;

IEEE 754 stipule : Pour un nombre à 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.
Pour un nombre à 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 significande M.

IEEE 754 a des réglementations spéciales sur le chiffre significatif M et l'exposant E. 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 ignoré, et seule la partie xxxxxx suivante est enregistrée. Par exemple, lors de l'enregistrement de 1.01, enregistrez uniquement 01, puis ajoutez le premier 1 lors de la lecture. Le but est d'économiser 1 chiffre significatif. En prenant le nombre à virgule flottante 32 bits comme exemple, il ne reste plus que 23 bits pour M. Une fois le premier 1 supprimé, cela équivaut à enregistrer 24 chiffres significatifs.

Quant à l'indice E, la situation est plus compliquée.
Tout d'abord, 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 à 2047. Cependant, nous savons que E en notation scientifique peut avoir des nombres négatifs, donc 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 chiffres, le nombre intermédiaire est 127 ; Pour un 11 bits E, ce nombre intermédiaire est 1023. Par exemple, le E de 2^10 est 10, donc lors de son enregistrement en tant que nombre à virgule flottante 32 bits, il doit être enregistré sous 10+127=137, soit 10001001.

Il existe trois cas d'extraction depuis la mémoire :

E n'est pas tout 0 ou pas tout 1.
A ce moment, 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, et puis le nombre effectif M est ajouté avant le premier chiffre
1. Par exemple : la forme binaire de 0,5 (1/2) est 0,1. Puisque la partie positive doit être 1, c'est-à-dire que la virgule décimale est décalée vers la droite d'un bit, alors elle est 1,0*2^(-1
) , et son code de commande est -1+127= 126, exprimé sous la forme 01111110, et la mantisse 1.0 supprime la partie entière pour être 0, et remplit 0 à 23 chiffres
000000000000000000000000, alors sa représentation binaire est :

0 01111110 00000000000000000000000

Lorsque E est tout 0
, l'exposant E du nombre à virgule flottante est égal à 1-127 (ou 1-1023), qui est la valeur réelle, et le nombre effectif M n'est plus additionné du premier chiffre de 1, mais est restauré à une décimale de 0.xxxxxx. Ceci est fait pour représenter ± 0 et de très petits nombres proches de 0.

Lorsque E est tout 1
, si le nombre effectif M est tout 0, cela signifie ± l'infini (positif ou négatif dépend du bit de signe s).

Laisse moi te donner un exemple:

#include <stdio.h>
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;
}

Résultats en cours d'exécution :
insérez la description de l'image ici
Alors pourquoi cela se produit : Nous avons la réserve de connaissances ci-dessus, et c'est beaucoup plus facile à expliquer.
Notre n est stocké en mémoire sous la forme d'un entier, et 9 est un nombre positif, donc le complément stocké en mémoire est :

00000000 00000000 00000000 00001001

pFloat est un type de pointeur flottant. Lorsque vous prenez n de la mémoire, il est extrait sous la forme d'un nombre à virgule flottante. Nous pouvons voir que 2-9 sont tous 0, donc cela correspond à un très petit nombre, donc c'est 0.

Ensuite, mettez 9,0 dans la mémoire sous la forme d'un nombre à virgule flottante comme suit : (-1) ^ 0 * 1,0010 * 2 ^ 3
où S = 1 ; E = 3 ; M = 1,001. Donc la suite binaire en mémoire est : 130

0 10000010 00100000000000000000000

Lorsque n est imprimé ci-dessous, il est sorti sous la forme du complément de l'entier et imprimé, donc ce qui est obtenu est un très grand nombre.

C'est tout pour le partage d'aujourd'hui, merci pour votre attention et votre soutien !

Je suppose que tu aimes

Origine blog.csdn.net/bushibrnxiaohaij/article/details/131527064
conseillé
Classement