C ++中算术运算的转换顺序是什么?

What is the casting order of operations in arithmetics in c++?

为什么

  1. result = static_cast<double>(1 / (i+1))

return int 在 C++ 中,为什么

  1. 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 是一个 inti+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 表达式,因为 i1 都是 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.

Arithmetic operators