Il existe un ensemble de conversions appelées usual arithmetic conversions qui sont utilisées avant l'évaluation de la plupart des opérateurs arithmétiques.
Fondamentalement, vous pouvez envisager qu'il y ait quelques règles pour l'arithmétique sur des entiers:
Tout d'abord, l'arithmétique entière est jamais réalisée avec opérandes « plus petit que » int
, donc dans le cas de short * signed char
, à la fois le short
et les opérandes signed char
sont promus à int
, les deux valeurs int
sont multipliées, puis le résultat est int
. Deuxièmement, si l'un des types ou les deux sont «plus grands que» int
, le compilateur sélectionne un type qui est au moins «aussi grand» que le type de l'opérande le plus grand. Donc, si vous avez long * int
, le int
est promu à un long
et le résultat est un long
. Troisièmement, si l'un des opérandes est unsigned
, le résultat est non signé. Donc, si vous avez long * unsigned int
, le long
et le unsigned int
sont tous les deux promus à un unsigned long
et le résultat est un unsigned long
.
Si l'un des opérandes est flottant type de point, puis arithmétique à virgule flottante est exécutée: float
, double
ou long double
est utilisé (que l'on dépend des types des opérandes, le tableau complet servant à déterminer le type de résultat peut être trouvé sur la page liée au début de cette réponse).
Notez que le type de résultat ne dépend pas des valeurs des opérandes. Le type doit être sélectionné par le compilateur au moment de la compilation, avant que les valeurs ne soient connues. Si le résultat de s * i * i
est hors de portée du type de résultat (int
, dans votre scénario), alors vous n'avez pas de chance: votre programme ne peut pas décider à l'exécution, "oh, je devrais passer à l'utilisation un long
! " parce que le type de résultat devait être sélectionné au moment de la compilation.
Merci, bonne réponse. – user3234