Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

Why does

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

return int in C++ and why does

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

return double? Specifically why is casting after the +-operation sufficient to produce a double. Why is it not required before the + or in the numerator as well? Is static_cast the preferred way of casting?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Code:

double harmonic(int n) {
  double result = 0;
  for (int i = 0; i < n; i++) {
    result += 1 / static_cast<double>(i+1);
  }
  return result;
}

>Solution :

There’s no such thing as "casting order" because the type of an expression depends on its operands. Put it simply, if a binary arithmetic operator accepts two operands of different types then the smaller type will be implicitly converted to the wider type

In result = static_cast<double>(1 / (i+1)) it’s parsed like this

  • i + 1 is an int expression since both i and 1 are of type int
  • 1 / (i + 1) returns int for the same reason
  • Then the result of 1 / (i + 1) is statically cast to double

OTOH in result = 1 / (i+static_cast<double>(1)) it’s like this

  • 1 is cast to double
  • i + static_cast<double>(1) returns double because i is cast to double due to the other operand
  • 1 / (i+static_cast<double>(1)) is a double expression for the same reason

But no one cast like that. It’s better to do 1 / (i + 1.0) instead

The complete rule is like this

  • 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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading