Compte tenu de l'extrait suivant:
1 4 8 10000 -1486618624
4 Réponses :
Le problème est que la multiplication est int32 * int32, qui est effectuée en tant quet32 et le résultat est ensuite attribué à un INT64. Vous obtiendrez beaucoup le même effet avec Vous devez faire attention au type d'expression ou de subexpression chaque fois que cela peut être important. Cela nécessite de s'assurer que l'opération appropriée est calculée en tant que type approprié, telle que la coulée d'une des multiplicandes à INT64, ou (dans mon exemple) double d = 3/2; code>, qui diviserait 3 par 2 à l'aide de la division entière et assigner 1,0 à
d p >
3.0 / 2 code> ou
(flotteur) 3/2 code>. p>
Très bien mis. @azraiyle doit changer cette ligne à int64 f = (int64) d * e; code>
Désolé que je n'ai pas déclaré que je connais la solution ici. Ce que je suis intéressé, c'est pourquoi la multiplication est int32 * int32 dans le premier cas et non int 8 * int8. Même si la CPU ne prend en charge que la multiplication INT32, elle peut être renvoyée à un INT8 après la multiplication. Mais l'instruction IA32 imul fonctionne pour les enregistreurs 8 bits (Al, ...).
@azrayl: au moins en C90, c promouvé tous les opérandes arithmétiques à INT code> s'ils étaient de types plus petits. Un coup d'œil à la norme C99 suggère que ce n'est plus le cas, mais je ne suis pas vraiment sûr. Quel compilateur C utilisez-vous et, le cas échéant, avec quelles options?
Si l'une des variables de type était plus grande qu'un INT (ou un point flottant), que ce type n'aurait été utilisé. Mais puisque tous les types utilisés dans les multiplies étaient int ou plus petits, des INT ont été utilisés. P> a * b code> est calculé comme un int, puis jeté sur le type de variable de réception (qui arrive tout simplement d'int) p>
d * e code> est calculé sous forme d'int, puis couler au type de variable de réception (qui vient d'être int64) p>
Lire K & R (l'original). Toutes les opérations entier sont effectuées avec le type entier naturel à moins que cela implique des variables (ou sont coulées) à quelque chose de plus grand. Les opérations de caractère sont coulées sur 32 bits car c'est la taille naturelle de l'entier sur cette architecture. La multiplication des deux entiers 32 bits est effectuée en 32 bits car rien ne le jette à rien de plus grand (jusqu'à ce que vous l'attribuiez à la variable 64 bits, mais c'est trop tard). Si vous voulez que l'opération se produise dans 64 bits, jetez une ou deux contre 64 bits.
int64 f = (int64)d * e;
La norme C99 spécifie que les opérateurs binaires tels que concernant Remarque: les règles de promotion distinguent des types signés et non signés lors de la promotion. La règle est de promouvoir des types plus petits à * code> ne fonctionnent pas sur des types d'entiers inférieurs à
int code>. Les expressions de ces types sont favorisées à
int code> avant l'application de l'opérateur. Voir 6.3.1.4 Paragraphe 2 et les nombreuses occurrences des mots «Promotion entière». Mais ceci est un peu orthogonal pour les instructions de montage générées par le compilateur, qui opère sur
int code> S, car il est plus rapide même lorsque le compilateur serait autorisé à calculer un résultat plus court (car le résultat est immédiatement stocké dans une valeur L d'un type court, par exemple). P>
int64 f = d * e; code> où
d code> et
E code> sont de type
int code>, la multiplication est fait comme un
int code> conformément aux mêmes règles de promotion. Le débordement est techniquement
int code> sauf si
int code> ne peut pas représenter toutes les valeurs du type, auquel cas
non signé INT code> est utilisé. p>