cpp/language/usual arithmetic conversions

Many binary operators that expect operands of or  type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions.

Definition
Usual arithmetic conversions are defined as follows: {{rrev|since=c++11|

Stage 1
}}
 * If either operand is of, no conversions are performed; if the other operand does not have the same type, the expression is ill-formed.
 * Otherwise, proceed to stage 2.

Stage 2

 * If either operand is of, the following rules are applied:
 * If both operands have the same type, no further conversion is needed.
 * Otherwise, if one of the operands is of a non-floating-point type, that operand is converted to the type of the other operand.
 * Otherwise, if the floating-point conversion ranks of the types of the operands are not equal, then the operand of the type with the lesser floating-point conversion rank is converted to the type of the other operand.


 * Otherwise, both operands are of integer types, proceed to stage 3.

Stage 3
Both operands are converted to a common type. Given the types and  as the promoted type  of the operands, the following rules are applied to determine :
 * If and  are the same type,  is that type.
 * Otherwise, if and  are both signed integer types or both unsigned integer types,  is the type of greater integer conversion rank.
 * Otherwise, one type between and  is an signed integer type, the other type is an unsigned integer type . Apply the follwing rules:
 * If the integer conversion rank of is greater than or equal to the integer conversion rank of,  is.
 * Otherwise, if can represent all of the values of,  is.
 * Otherwise, is the unsigned integer type corresponding to.

Integer conversion rank
Every has an integer conversion rank defined as follows:
 * No two signed integer types other than and  (if  is signed) have the same rank, even if they have the same representation.
 * The rank of a signed integer type is greater than the rank of any signed integer type with a smaller width.
 * The ranks of the following integer types decrease in order:




 * The rank of any unsigned integer type equals the rank of the corresponding signed integer type.


 * The rank of is less than the rank of all standard integer types.
 * The ranks of encoding character types ( and ) equal the ranks of their, which means:
 * The rank of equals the rank of  and.


 * The rank of equals the rank of its implementation-defined underlying type.


 * For all integer types, , and , if has greater rank than  and  has greater rank than , then  has greater rank than.

The integer conversion rank is also used in the definition of.

Floating-point conversion rank
Every has a floating-point conversion rank defined as follows:
 * The ranks of the standard floating-point types decrease in order:

{{rrev|since=c++23|

Floating-point conversion subrank
Floating-point types that have equal floating-point conversion ranks are ordered by floating-point conversion subrank. The subrank forms a total order among types with equal ranks.

The types, , , and (fixed width floating-point types) have a greater conversion subrank than any standard floating-point type with equal conversion rank. Otherwise, the conversion subrank order is implementation-defined. }}

Usage
The floating-point conversion rank and subrank are also used to
 * determine whether a conversion between different floating-point types or is a ,
 * in overload resolution,


 * determine whether std's converting constructor is explicit, or
 * determine the common floating-point type if the arguments of different floating-point types are passed to common or special math functions.