It depends on exactly how the expression was written.
If you write this:
my_large_double / my_large_int1 / my_large_int2
then it's equivalent to:
(my_large_double / my_large_int1) / my_large_int2
which should give you reasonably accurate results; my_large_int1
is promoted to double
before the first division, and my_large_int2
is promoted to double
before the second division.
If you write this:
my_large_double / (my_large_int1 * my_large_int2)
then the multiplication is done in the type of the two integer variables, and depending on their values you could have an overflow (which can give you a much smaller value than the mathematical product -- though strictly speaking the behavior of signed integer overflow is undefined).
The important thing to remember is that, in most cases, each C expression is effectively evaluated in isolation; its type is not affected by the context in which it appears. The expression my_large_int1 * my_large_int2
is an integer multiplication, even if the result is the operand of a floating-point division or is assigned to a floating-point variable.
Any operation whose operands are both integers is an integer operation. If one operand is double
and the other is int
, the int
operand is promoted to double
.
Even this:
double temp = my_large_int1 * my_large_int2;
... my_large_double / temp ...
will perform an integer multiplication before using the result to initialize temp
, and this:
my_large_double / (double)(my_large_int1 * my_large_int2)
has the same problem.
As you've found, the solution is to cast one or both of the integer operands to double
:
my_large_double / ((double)my_large_int1 * (double)my_large_int2)
(You might as well cast both of them, just for symmetry and clarity.)