Je pense que le moyen le plus simple d'expliquer cela est de le décomposer dans l'ordre des opérations que vous effectuez.
Instance | # int | char | # byte | result |
Source | 11 11 11 11 | 11 11 11 11 | 11 11 11 11 | 11 11 11 10 | -2 |
byte |(11 11 11 11)|(11 11 11 11)|(11 11 11 11)| 11 11 11 10 | -2 |
int | 11 11 11 11 | 11 11 11 11 | 11 11 11 11 | 11 11 11 10 | -2 |
char |(00 00 00 00)|(00 00 00 00)| 11 11 11 11 | 11 11 11 10 | 65534 |
int | 00 00 00 00 | 00 00 00 00 | 11 11 11 11 | 11 11 11 10 | 65534 |
- Vous prenez simplement une valeur signée de 32 bits.
- Vous le convertissez ensuite en une valeur signée de 8 bits.
- Lorsque vous tentez de le convertir en une valeur non signée de 16 bits, le compilateur effectue une conversion rapide en une valeur signée de 32 bits,
- Ensuite, on le convertit en 16 bits sans maintenir le signe.
- Lors de la conversion finale en 32 bits, il n'y a pas de signe, donc la valeur ajoute zéro bit pour maintenir la valeur.
Donc, oui, quand vous regardez de cette façon, l'octet lancé est significatif (académiquement parlant), bien que le résultat soit insignifiant (joie de la programmation, une action significative peut avoir un effet insignifiant). L'effet de rétrécissement et d'élargissement tout en maintenant le signe. La conversion en char rétrécit, mais ne s'élargit pas au signe.
(Veuillez noter que j'ai utilisé un # pour indiquer le bit signé, et comme indiqué, il n'y a pas de bit signé pour char, car c'est une valeur non signée).
J'ai utilisé des parenthèses pour représenter ce qui se passe réellement en interne. Les types de données sont en fait regroupés dans leurs blocs logiques, mais s'ils étaient vus comme dans int, leurs résultats seraient ce que les parenthèses symbolisent.
Les valeurs signées s'élargissent toujours avec la valeur du bit signé. Les valeurs non signées s'élargissent toujours avec le bit désactivé.
*Ainsi, l'astuce (ou les problèmes) est que l'expansion en int à partir de byte, maintient la valeur signée lorsqu'elle est élargie. Qui est ensuite rétrécie au moment où elle touche le char. Cela désactive alors le bit signé.
Si la conversion en int n'avait pas eu lieu, la valeur aurait été 254. Mais elle a lieu, donc elle ne l'est pas.