Hay un conjunto de conversiones llamadas usual arithmetic conversions que se utilizan antes de la evaluación de la mayoría de los operadores aritméticos.
Básicamente, se puede considerar que haya algunas reglas para la aritmética de números enteros:
En primer lugar, la aritmética de enteros no se realiza con operandos "más pequeño que" int
, por lo que en el caso de short * signed char
, tanto los short
y signed char
operandos se promueven a int
, los dos valores de int
se multiplican y el resultado es int
.
En segundo lugar, si uno o ambos tipos son "mayores que" int
, el compilador selecciona un tipo que es al menos "tan grande" como el tipo del operando más grande. Por lo tanto, si tiene long * int
, se promociona int
a long
y el resultado es long
.
En tercer lugar, si cualquiera de los dos operandos es unsigned
, el resultado no está firmado. Por lo tanto, si tiene long * unsigned int
, el long
y el unsigned int
son promovidos a un unsigned long
y el resultado es un unsigned long
.
Si alguno de los operandos ha flotante tipo de punto, la aritmética de coma luego flotante se lleva a cabo: float
, se utiliza double
, o long double
(que uno depende de los tipos de los operandos; la tabla completa se utiliza para determinar el tipo de resultado se puede encontrar en la página vinculada al comienzo de esta respuesta).
Tenga en cuenta que el tipo de resultado no depende de los valores de los operandos. El compilador debe seleccionar el tipo en el momento de la compilación, antes de conocer los valores.
Si el resultado de s * i * i
está fuera del rango del tipo de resultado (int
, en su escenario), entonces no tiene suerte: su programa no puede decidir en tiempo de ejecución, "oh, debería cambiar para usar a long
! " porque el tipo de resultado tuvo que ser seleccionado en tiempo de compilación.
Gracias, buena respuesta. – user3234