I want to be better about knowing when I should cast. What are the implicit type conversion rules in C++ when adding, multiplying, etc. For example,
int + fl
Since the other answers don't talk about the rules in C++11 here's one. From C++11 standard (draft n3337) §5/9 (emphasized the difference):
This pattern is called the usual arithmetic conversions, which are defined as follows:
— If either operand is of scoped enumeration type, no conversions are performed; if the other operand does not have the same type, the expression is ill-formed.
— If either operand is of type long double, the other shall be converted to long double.
— Otherwise, if either operand is double, the other shall be converted to double.
— Otherwise, if either operand is float, the other shall be converted to float.
— Otherwise, the integral promotions shall be performed on both operands. Then the following rules shall be applied to the promoted operands:
— If both operands have the same type, no further conversion is needed.
— Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.
— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
— Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.
— Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
See here for a list that's frequently updated.
In C++ operators (for POD types) always act on objects of the same type.
Thus if they are not the same one will be promoted to match the other.
The type of the result of the operation is the same as operands (after conversion).
If either is long double the other is promoted to long double
If either is double the other is promoted to double
If either is float the other is promoted to float
If either is long long unsigned int the other is promoted to long long unsigned int
If either is long long int the other is promoted to long long int
If either is long unsigned int the other is promoted to long unsigned int
If either is long int the other is promoted to long int
If either is unsigned int the other is promoted to unsigned int
If either is int the other is promoted to int
Both operands are promoted to int
Note. The minimum size of operations is int
. So short
/char
are promoted to int
before the operation is done.
In all your expressions the int
is promoted to a float
before the operation is performed. The result of the operation is a float
.
int + float => float + float = float
int * float => float * float = float
float * int => float * float = float
int / float => float / float = float
float / int => float / float = float
int / int = int
int ^ float => <compiler error>
Whole chapter 4 talks about conversions, but I think you should be mostly interested in these :
4.5 Integral promotions
[conv.prom]
An rvalue of type char, signed char, unsigned char, short int, or unsigned short
int can be converted to an rvalue of type int if int can represent all the values of the source type; other-
wise, the source rvalue can be converted to an rvalue of type unsigned int.
An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first
of the following types that can represent all the values of its underlying type: int, unsigned int,
long, or unsigned long.
An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all
the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can rep-
resent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the
bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes.
An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true
becoming one.
These conversions are called integral promotions.
4.6 Floating point promotion
[conv.fpprom]
An rvalue of type float can be converted to an rvalue of type double. The value is unchanged.
This conversion is called floating point promotion.
Therefore, all conversions involving float - the result is float.
Only the one involving both int - the result is int : int / int = int