C ++中算术运算的转换顺序是什么?
What is the casting order of operations in arithmetics in c++?
为什么
result = static_cast<double>(1 / (i+1))
return int
在 C++ 中,为什么
result = 1 / (i+static_cast<double>(1))
returndouble
?具体来说,为什么在 +
操作之后进行转换足以产生 double
。为什么在 +
之前或分子中也不需要它? static_cast
是首选的投射方式吗?
代码:
double harmonic(int n) {
double result = 0;
for (int i = 0; i < n; i++) {
result += 1 / static_cast<double>(i+1);
}
return result;
}
static_cast<double>(1 / (i+1));
首先,1 / (i+1)
进行评估。因为 1 是一个 int
而 i+1
是一个 int
,所以这是整数除法,所以 1/(i+1)
是一个 int
。然后将结果类型转换为 double
。所以从技术上讲,static_cast<double>(1 / (i+1));
returns一个double
,但是结果丢失了,因为1/(i+1)
是整数除法
result += 1 / static_cast<double>(i+1);
现在因为 static_cast<double>(i+1)
是双精度数,1 / static_cast<double>(i+1);
现在是浮点数除法,因此 1 / static_cast<double>(i+1);
是 double
你应该知道Integer Divison
您可以使用此代码查看,它实际上 returns 是一个双精度数。但是,由于整数除法,它将始终为零(或 nan)。
#include <iostream>
using std::cout;
int main()
{
int i = 5;
cout << typeid(static_cast<double>(1 / (i+1))).name() << "\n"; // d for double
return 0;
}
您可以通过不除以两个整数来规避整数除法。因此,其中一个是双倍的就足够了。
int + double == double
double + int == double
int / double == double
double / int == double
所以你可以看到,只需要将一个被加数转换为 double,以便将整个表达式变成一个 double,它并不总是零。
没有“转换顺序”这样的东西,因为表达式的类型取决于它的操作数。简单来说,如果一个二元算术运算符接受两个不同类型的操作数,那么较小的类型将隐式转换为较宽的类型
在result = static_cast<double>(1 / (i+1))
中是这样解析的
i + 1
是一个 int
表达式,因为 i
和 1
都是 int
类型
1 / (i + 1)
returns int 同理
- 然后
1 / (i + 1)
的结果静态转换为double
result = 1 / (i+static_cast<double>(1))
中的 OTOH 是这样的
1
转换为 double
i + static_cast<double>(1)
returns double
因为 i
由于另一个操作数 被强制转换为 double
1 / (i+static_cast<double>(1))
是一个 double
表达式,原因相同
但是没有人那样投。最好做 1 / (i + 1.0)
而不是
完整的规则是这样的
- If either operand has scoped enumeration type, no conversion is performed: the other operand and the return type must have the same type
- Otherwise, if either operand is
long double
, the other operand is converted to long double
- Otherwise, if either operand is
double
, the other operand is converted to double
- Otherwise, if either operand is
float
, the other operand is converted to float
- Otherwise, the operand has integer type (because
bool
, char
, char8_t
, char16_t
, char32_t
, wchar_t
, and unscoped enumeration were promoted at this point) and integral conversions are applied to produce the common type, as follows:
- If both operands are signed or both are unsigned, the operand with lesser conversion rank is converted to the operand with the greater integer conversion rank
- Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand's type.
- Otherwise, if the signed operand's type can represent all values of the unsigned operand, the unsigned operand is converted to the signed operand's type
- Otherwise, both operands are converted to the unsigned counterpart of the signed operand's type.
The conversion rank above increases in order bool
, signed char
, short
, int
, long
, long long
. The rank of any unsigned type is equal to the rank of the corresponding signed type. The rank of char
is equal to the rank of signed char
and unsigned char
. The ranks of char8_t
, char16_t
, char32_t
, and wchar_t
are equal to the ranks of their underlying types.
为什么
result = static_cast<double>(1 / (i+1))
return int
在 C++ 中,为什么
result = 1 / (i+static_cast<double>(1))
returndouble
?具体来说,为什么在 +
操作之后进行转换足以产生 double
。为什么在 +
之前或分子中也不需要它? static_cast
是首选的投射方式吗?
代码:
double harmonic(int n) {
double result = 0;
for (int i = 0; i < n; i++) {
result += 1 / static_cast<double>(i+1);
}
return result;
}
static_cast<double>(1 / (i+1));
首先,1 / (i+1)
进行评估。因为 1 是一个 int
而 i+1
是一个 int
,所以这是整数除法,所以 1/(i+1)
是一个 int
。然后将结果类型转换为 double
。所以从技术上讲,static_cast<double>(1 / (i+1));
returns一个double
,但是结果丢失了,因为1/(i+1)
是整数除法
result += 1 / static_cast<double>(i+1);
现在因为 static_cast<double>(i+1)
是双精度数,1 / static_cast<double>(i+1);
现在是浮点数除法,因此 1 / static_cast<double>(i+1);
是 double
你应该知道Integer Divison
您可以使用此代码查看,它实际上 returns 是一个双精度数。但是,由于整数除法,它将始终为零(或 nan)。
#include <iostream>
using std::cout;
int main()
{
int i = 5;
cout << typeid(static_cast<double>(1 / (i+1))).name() << "\n"; // d for double
return 0;
}
您可以通过不除以两个整数来规避整数除法。因此,其中一个是双倍的就足够了。
int + double == double
double + int == double
int / double == double
double / int == double
所以你可以看到,只需要将一个被加数转换为 double,以便将整个表达式变成一个 double,它并不总是零。
没有“转换顺序”这样的东西,因为表达式的类型取决于它的操作数。简单来说,如果一个二元算术运算符接受两个不同类型的操作数,那么较小的类型将隐式转换为较宽的类型
在result = static_cast<double>(1 / (i+1))
中是这样解析的
i + 1
是一个int
表达式,因为i
和1
都是int
类型
1 / (i + 1)
returns int 同理- 然后
1 / (i + 1)
的结果静态转换为double
result = 1 / (i+static_cast<double>(1))
中的 OTOH 是这样的
1
转换为double
i + static_cast<double>(1)
returnsdouble
因为i
由于另一个操作数 被强制转换为 1 / (i+static_cast<double>(1))
是一个double
表达式,原因相同
double
但是没有人那样投。最好做 1 / (i + 1.0)
而不是
完整的规则是这样的
- If either operand has scoped enumeration type, no conversion is performed: the other operand and the return type must have the same type
- Otherwise, if either operand is
long double
, the other operand is converted tolong double
- Otherwise, if either operand is
double
, the other operand is converted todouble
- Otherwise, if either operand is
float
, the other operand is converted tofloat
- Otherwise, the operand has integer type (because
bool
,char
,char8_t
,char16_t
,char32_t
,wchar_t
, and unscoped enumeration were promoted at this point) and integral conversions are applied to produce the common type, as follows:
- If both operands are signed or both are unsigned, the operand with lesser conversion rank is converted to the operand with the greater integer conversion rank
- Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand's type.
- Otherwise, if the signed operand's type can represent all values of the unsigned operand, the unsigned operand is converted to the signed operand's type
- Otherwise, both operands are converted to the unsigned counterpart of the signed operand's type.
The conversion rank above increases in order
bool
,signed char
,short
,int
,long
,long long
. The rank of any unsigned type is equal to the rank of the corresponding signed type. The rank ofchar
is equal to the rank ofsigned char
andunsigned char
. The ranks ofchar8_t
,char16_t
,char32_t
, andwchar_t
are equal to the ranks of their underlying types.