Il me semble que vous ne comprenez pas vraiment ce qu'est une union. Les membres d'une union sont des valeurs qui se chevauchent (en d'autres termes, les trois membres d'un Count
union partagent le même espace).
En supposant, pour le plaisir de démonstration, une short
est de 16 bits (2 octets), un float
est de 32 bits (4 octets) et un double
est de 64 bits (8 octets), alors l'union est de 8 octets dans Taille. Dans le format little-endian, le membre num
fait référence aux 2 premiers octets, le membre weight
fait référence aux 4 premiers octets (y compris les 2 octets de num
) et le membre de volume fait référence aux 8 octets complets (y compris les 2 octets de num
et les quatre octets de weight
).
Dans un premier temps, votre syndicat contient des déchets, à savoir une configuration binaire inconnu, Affichons comme ça (en hexadécimal):
GG GG GG GG GG GG GG GG // GG stands for garbage, i.e. unknown bit patterns
Si vous définissez num
-2, les deux premiers octets sont 0x02
0x00
, mais les autres octets sont encore des déchets:
02 00 GG GG GG GG GG GG
Si vous lisez weight
, vous lisez simplement les quatre premiers octets, interprétés comme float
, de sorte que le float
contient les octets
02 00 GG GG
Puisque les valeurs à virgule flottante ont un format totalement différent que les types entiers comme short
, vous ne pouvez pas prédire ce que ces octets (à savoir ce modèle de bits particulier) représentent. Ils ne représentent pas la valeur en virgule flottante 2.0f, ce que vous voulez probablement. En fait, la « plus importante » partie d'un float
est stocké dans les octets supérieurs, à savoir dans la partie « déchets » de weight
, il peut donc être presque tout, y compris un NaN
, +infinity
, -infinity
, etc.
De même , si vous lisez volume
, vous avez un double
qui se compose des octets
02 00 GG GG GG GG GG GG
et qui ne représente pas nécessairement 2.0 soit (bien que, par hasard, il PEUT venir très près, si par coïncidence les bons bits sont placés aux bons endroits, et si les bits faibles sont arrondis lorsque vous affichez une telle valeur).
Les unions ne sont pas destinées à effectuer une conversion appropriée de int
à float
ou double
. Ils sont simplement destinés à être en mesure de stocker différents types de valeurs pour le même type, et lire un autre membre que vous définissez simplement signifie que vous êtes réinterpréter un nombre de bits qui sont présents dans l'union comme quelque chose de complètement différent. Vous n'êtes pas en train de convertir.
Alors comment convertir? Il est assez simple et ne nécessite pas une union:
short num = 2;
float weight = num; // the compiler inserts code that performs a conversion to float
double volume = num; // the compiler inserts code that performs a conversion to double
Ne vous attendez pas à ce que le comportement indéfini soit défini. – chris
Vous définissez seulement la partie 'short' de cette union à une certaine valeur. Le reste contiendra des données aléatoires à chaque réexécution. – usr2564301
Alors qu'est-ce qu'un garçon est supposé faire? Il suffit de prendre le poids de votre pomme hors de l'air –