1

What is the difference between

unsigned int n = (n2-n1)/n3 + 1;

and

double N = (n2-n1)/n3 + 1;

unsigned int n = (unsigned int)(N);

where n1, n2, and n3 are doubles? I am asking this because with n1=3, n2=4 and n3=0.1, n gets 10 in the first case and 11 in the second (at least on my computer). The correct answer is 11 so the result of the first one is wrong. I am guessing it has something to do with truncation to unsigned int. Is that right? Is the right hand side expression in the first case not calculated as double first, before being cast into unsigned int (in which case it would be equivalent to the second piece of code)? Also, is there a way to get the shorter expression (the first one) to work?

Mo Sanei
  • 445
  • 6
  • 22
  • 1
    The expression `(n2-n1)/n3 + 1` might be a register value (extended double). After storing it to N it is a (likely rounded) double. Yes it is a truncation issue. –  Aug 03 '16 at 19:20
  • It is very likely that the first expression returns something slightly below 11, so it is truncated to 10. The difference is that the first one may be an extended precision intermediate value that is truncated, while in the second example, it is guaranteed that a double is truncated. – Rudy Velthuis Aug 03 '16 at 19:21

1 Answers1

2

Is the right hand side expression in the first case not calculated as double first, before being cast into unsigned int.

Not necessarily. It might be computed as long double, which might result in a different truncation than double. Different compilers or different compiler options might produce a different result.

Is there a way to get the shorter expression (the first one) to work?

Rounding is often a much better strategy than truncation, particularly if you are expecting the result to be very close to an integer.

Standard reference:

§6.3.1.8 (Usual arithmetic conversions), paragraph 2, with relevant footnote:

The values of floating operands and of the results of floating expressions may be represented in greater range and precision than that required by the type; the types are not changed thereby. (63)

63) The cast and assignment operators are still required to remove extra range and precision.

rici
  • 234,347
  • 28
  • 237
  • 341