我想知道什么时候该投。在c++中,当进行加法、乘法等操作时,隐式类型转换规则是什么?例如,

int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?

等等...

表达式是否总是计算为更精确的类型?Java的规则不同吗? 如果我在这个问题上用词不准确,请指正。


当前回答

我对这个问题的解决方案得到了WA(错误的答案),然后我将int中的一个改为long long int,它给出了AC(接受)。之前,我试图做long long int += int * int,在我将其纠正为long long int += long long int * int后。我在谷歌上搜了一下,

1. 算术转换

类型转换条件:

条件满足—>转换

Either operand is of type long double. ---> Other operand is converted to type long double. Preceding condition not met and either operand is of type double. ---> Other operand is converted to type double. Preceding conditions not met and either operand is of type float. ---> Other operand is converted to type float. Preceding conditions not met (none of the operands are of floating types). ---> Integral promotions are performed on the operands as follows: If either operand is of type unsigned long, the other operand is converted to type unsigned long. If preceding condition not met, and if either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long. If the preceding two conditions are not met, and if either operand is of type long, t he other operand is converted to type long. If the preceding three conditions are not met, and if either operand is of type unsigned int, the other operand is converted to type unsigned int. If none of the preceding conditions are met, both operands are converted to type int.

2。整数转换规则

整数的促销活动:

小于int的整数类型在对其执行操作时被提升。如果原始类型的所有值都可以表示为int型,则较小类型的值转换为int型;否则,它将被转换为无符号整型。整数提升作为对某些参数表达式的常规算术转换的一部分应用;一元+、-和~操作符的操作数;和移位操作符的操作数。

Integer Conversion Rank: No two signed integer types shall have the same rank, even if they have the same representation. The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision. The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char. The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any. The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width. The rank of char shall equal the rank of signed char and unsigned char. The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined but still subject to the other rules for determining the integer conversion rank. For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3. Usual Arithmetic Conversions: If both operands have the same type, no further conversion is needed. If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. 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 is converted to the type of the operand with unsigned integer type. 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 is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. Specific operations can add to or modify the semantics of the usual arithmetic operations.

其他回答

If you exclude the unsigned types, there is an ordered hierarchy: signed char, short, int, long, long long, float, double, long double. First, anything coming before int in the above will be converted to int. Then, in a binary operation, the lower ranked type will be converted to the higher, and the results will be the type of the higher. (You'll note that, from the hierarchy, anytime a floating point and an integral type are involved, the integral type will be converted to the floating point type.)

Unsigned让事情变得有点复杂:它会影响排名,而且 部分排名变成实现定义。因为 最好不要把有符号和无符号混合在一起 表达式。(大多数c++专家似乎都避免使用unsigned除非 涉及到按位操作。那至少是什么 Stroustrup建议)。

在c++中,操作符(用于POD类型)总是作用于相同类型的对象。 因此,如果它们不相同,其中一个将被提升到与另一个匹配。 操作结果的类型与操作数(转换后)相同。

if:
either is      long double       other is promoted >      long double
either is           double       other is promoted >           double
either is           float        other is promoted >           float
either is long long unsigned int other is promoted > long long unsigned int
either is long long          int other is promoted > long long          int
either is long      unsigned int other is promoted > long      unsigned int
either is long               int other is promoted > long               int
either is           unsigned int other is promoted >           unsigned int
either is                    int other is promoted >                    int

Otherwise:
both operands are promoted to int

请注意。操作的最小大小是int。因此,short/char在操作完成之前被提升为int。

在所有表达式中,int在执行操作之前被提升为浮点数。操作的结果是一个浮点数。

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>

这个答案在很大程度上是针对@ rafajdowgird的评论:

操作的最小大小是int。-这太奇怪了 (那么有效支持char/short的架构呢 操作?)这真的在c++规范中吗?

请记住,c++标准有非常重要的“as-if”规则。参见第1.8节:程序执行:

3)这一规定有时被称为“假设”规则,因为a 执行可以自由地忽略标准的任何要求 只要结果是满足了要求,就可以 这可以从程序的可观察行为中确定。

编译器不能将int值设置为8位,即使它是最快的,因为标准要求最小int值为16位。

因此,在具有超快8位操作的理论计算机的情况下,将算术隐式提升为int可能很重要。然而,对于许多操作,您无法判断编译器是否确实以int精度执行了操作,然后将其转换为char类型存储在您的变量中,或者这些操作是否始终以char类型完成。

For example, consider unsigned char = unsigned char + unsigned char + unsigned char, where addition would overflow (let's assume a value of 200 for each). If you promoted to int, you would get 600, which would then be implicitly down cast into an unsigned char, which would wrap modulo 256, thus giving a final result of 88. If you did no such promotions,you'd have to wrap between the first two additions, which would reduce the problem from 200 + 200 + 200 to 144 + 200, which is 344, which reduces to 88. In other words, the program does not know the difference, so the compiler is free to ignore the mandate to perform intermediate operations in int if the operands have a lower ranking than int.

这在一般的加法、减法和乘法中都是成立的。对于除法和模量来说,一般不是这样的。

整个第4章都在讲转换,但我认为你应该对这些最感兴趣:

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浮点提升 (conv.fpprom) float类型的右值可以转换为double类型的右值。该值不变。 这种转换称为浮点提升。

因此,所有涉及浮点数的转换结果都是浮点数。

只有一个包含两个int -结果是int: Int / Int = Int

我对这个问题的解决方案得到了WA(错误的答案),然后我将int中的一个改为long long int,它给出了AC(接受)。之前,我试图做long long int += int * int,在我将其纠正为long long int += long long int * int后。我在谷歌上搜了一下,

1. 算术转换

类型转换条件:

条件满足—>转换

Either operand is of type long double. ---> Other operand is converted to type long double. Preceding condition not met and either operand is of type double. ---> Other operand is converted to type double. Preceding conditions not met and either operand is of type float. ---> Other operand is converted to type float. Preceding conditions not met (none of the operands are of floating types). ---> Integral promotions are performed on the operands as follows: If either operand is of type unsigned long, the other operand is converted to type unsigned long. If preceding condition not met, and if either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long. If the preceding two conditions are not met, and if either operand is of type long, t he other operand is converted to type long. If the preceding three conditions are not met, and if either operand is of type unsigned int, the other operand is converted to type unsigned int. If none of the preceding conditions are met, both operands are converted to type int.

2。整数转换规则

整数的促销活动:

小于int的整数类型在对其执行操作时被提升。如果原始类型的所有值都可以表示为int型,则较小类型的值转换为int型;否则,它将被转换为无符号整型。整数提升作为对某些参数表达式的常规算术转换的一部分应用;一元+、-和~操作符的操作数;和移位操作符的操作数。

Integer Conversion Rank: No two signed integer types shall have the same rank, even if they have the same representation. The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision. The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char. The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any. The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width. The rank of char shall equal the rank of signed char and unsigned char. The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined but still subject to the other rules for determining the integer conversion rank. For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3. Usual Arithmetic Conversions: If both operands have the same type, no further conversion is needed. If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. 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 is converted to the type of the operand with unsigned integer type. 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 is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. Specific operations can add to or modify the semantics of the usual arithmetic operations.