Why does, for example, the result of operation between an unsigned short
and int
always yields an int
?
unsigned short s = 65535;
int i = 65535
Expression typeid(s * i * i).name()
, gives a value which is out of the range of an int
but still the implicit conversion returns an int
, why?
There are a set of conversions called the usual arithmetic conversions that are used prior to the evaluation of most arithmetic operators.
Basically, you can consider there to be a few rules for arithmetic on integers:
First, integer arithmetic is never performed with operands "smaller than" int
, so in the case of short * signed char
, both the short
and the signed char
operands are promoted to int
, the two int
values are multiplied, and then the result is an int
.
Second, if one or both of the types are "larger than" int
, the compiler selects a type that is at least "as large" as the type of the largest operand. So, if you have long * int
, the int
is promoted to a long
and the result is a long
.
Third, if either operand is unsigned
, then the result is unsigned. So, if you have long * unsigned int
, the long
and the unsigned int
are both promoted to an unsigned long
and the result is an unsigned long
.
If either operand has floating point type, then floating point arithmetic is performed: float
, double
, or long double
is used (which one depends on the types of the operands; the full table used to determine the result type can be found on the page linked at the beginning of this answer).
Note that the result type is not dependent upon the values of the operands. The type has to be selected by the compiler at compile time, before the values are known.
If the result of s * i * i
is out of range of the result type (int
, in your scenario), then you're out of luck: your program can't decide at runtime, "oh, I should switch to use a long
!" because the result type had to be selected at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With