En regardant ce code C# :
byte x = 1;
byte y = 2;
byte z = x + y; // ERROR: Cannot implicitly convert type 'int' to 'byte'
Le résultat de tout calcul effectué sur byte
(ou short
) est implicitement retransformé en un nombre entier. La solution consiste à convertir explicitement le résultat en un octet :
byte z = (byte)(x + y); // this works
Ce que je me demande, c'est pourquoi ? Est-ce architectural ? Philosophique ?
Nous avons :
-
int
+int
=int
-
long
+long
=long
-
float
+float
=float
-
double
+double
=double
Alors pourquoi pas :
-
byte
+byte
=byte
-
short
+short
=short
?
Un peu de contexte : J'effectue une longue liste de calculs sur des "petits nombres" (c'est-à-dire < 8) et je stocke les résultats intermédiaires dans un grand tableau. En utilisant un tableau d'octets (au lieu d'un tableau d'int) est plus rapide (à cause des hits de cache). Mais les nombreux byte-casts répartis dans le code le rendent d'autant plus illisible.
6 votes
stackoverflow.com/questions/927391/
0 votes
Je suppose que c'est lié à la facilité avec laquelle on peut faire déborder un octet avec quelques ajouts. Cependant, je pense que c'est au programmeur de s'en occuper, plutôt qu'à l'architecte de le restaurer comme ça.
1 votes
Etes-vous sûr que vous n'êtes pas en train de micro-optimiser cela ? IIRC, sur une machine 32 bits, les octets sont alignés sur les frontières 32 bits pour un accès optimisé, c'est-à-dire qu'un octet utilise en réalité 4 octets en mémoire.
2 votes
Eric Lippert, où es-tu quand on a besoin de toi ?? Connaissance encyclopédique du standard C#, à la rescousse !
10 votes
Ce n'est pas la connaissance d'Eric de la standard qui serait utile ici - c'est sa connaissance des design de la langue ; quoi et non pourquoi. Mais oui, la réponse d'Eric serait assez définitive :)
147 votes
Les diverses réflexions ci-dessous sont une approximation raisonnable des considérations de conception. Plus généralement : Je ne vois pas les octets comme des "nombres" ; je les vois comme des modèles de bits qui pourraient être interprétées comme des nombres, des caractères, des couleurs ou autres. Si vous devez faire des calculs sur eux et les traiter comme des nombres, il est logique de déplacer le résultat dans un type de données qui est plus communément interprété comme un nombre.
31 votes
@Eric : Cela a beaucoup de sens pour l'octet, mais probablement pas autant pour le court/court.
1 votes
Eric - votre commentaire est vraiment la meilleure réponse à cette question. Vous voulez créer une réponse à cette question ?
2 votes
Ce que Michael a dit. Fais-en une réponse et je l'upvote.
1 votes
Au fait, si vos chiffres sont toujours inférieurs à 8, vous pouvez enregistrer deux d'entre eux par octet et de diviser par deux vos manques de cache encore une fois.
24 votes
@Eric :
byte1 | byte2
n'est pas du tout de les traiter comme des numéros. C'est les traiter précisément comme des modèles de bits. Je comprends votre point de vue, mais il se trouve qu'à chaque fois que j'ai effectué une opération arithmétique sur des octets en C#, je les traitais en fait comme des bits, et non comme des nombres, et ce comportement est toujours gênant.0 votes
@Crashworks même si les octets semblent n'avoir que 8 bits, c# les arrondit probablement sur une limite de 4 ou 8 octets sur la pile lorsqu'ils sont utilisés comme variables locales. C'est exactement la même chose pour l'utilisation des registres - même si les registres sur 86 sont de 32 bits, l'asm généré à partir de msil ne va pas empaqueter des variables de 4 octets dans un registre. il va y avoir beaucoup de chargement et de sauvegarde comme pour les valeurs de 32 bits.
4 votes
Duplicata possible de Blues de la somme des nombres entiers, problème court += court
0 votes
@GSerg Cette question était la première et a chemin plus de votes à tous les niveaux. Tu t'es trompé dans la direction de la fermeture.
0 votes
@RobertCartaino Oui, cette question est plus ancienne, mais l'autre contient une réponse beaucoup plus précieuse d'Eric Lippert. Je la proposerais comme réponse canonique .
0 votes
@GSerg Alors les questions auraient dû être fusionnées, mais c'est une affirmation vraiment dangereuse de juger une question sommairement par "qui" y a répondu plutôt que par le filtrage du contenu. Eric Lippert a également commenté la question ici et j'ai un Jon Skeet. Ma paire a battu votre one of a kind ; pas sûr que nous devrions jouer à ce jeu. Gast, ça va sembler assez drôle que j'aie écrit sur le sujet de la mérites de cette question particulière (des centaines de fois) pour découvrir qu'elle a été fermée par la communauté. Classique.
0 votes
@RobertCartaino Puis faites le vote final de clôture, rouvrez et laissez un lien vers l'autre. Je ne cherche pas à fermer toutes les questions sauf une, je veux juste qu'elles soient toutes liées.
0 votes
Voici une réponse que j'ai rédigée ailleurs et qui contient un programme permettant d'identifier quand cette promotion automatique à l'aide d'un compilateur vers le statut de "personne".
int
se produit (en C ou C++ au moins) : stackoverflow.com/a/43578929/45618871 votes
@EricLippert, (oui, je sais que c'est des années plus tard) cela n'explique pas pourquoi le même problème existe pour effectuer des opérations logiques sur les éléments suivants
byte
s.