The difference likely occurs when d * g
is evaluated, because the mathematical result of that product must be rounded upward to produce a value representable in double
, but the long double
result is more accurate.
Most compilers convert 405
and 63
to double
exactly and convert 9.8
to 9.800000000000000710542735760100185871124267578125, although the C++ standard gives them some leeway. The evaluation of v * v
is also generally exact, since the mathematical result is exactly representable.
Commonly, on Intel processors, compilers evaluate d * g
in one of two ways: Using double
arithmetic or using long double
with Intel’s 80-bit floating-point format. When evaluated with double
, 405•9.800000000000000710542735760100185871124267578125 produces 3969.00000000000045474735088646411895751953125, and dividing this by 3969 yields a number slightly greater than one.
When evaluated with long double
, the product is 3969.000000000000287769807982840575277805328369140625. The product, although greater than 3969, is slightly less, and dividing it by 3969 using long double
arithmetic produces
1.000000000000000072533125339280246635098592378199100494384765625. When this value is assigned to r
, the compiler is required to convert it to double
. (Extra precision may be used only in intermediate expressions, not in assignments or casts.) This value is sufficient close to one that rounding it to double
produces one.
You can mitigate some (but not all) of the variation between compilers by using casts or assignments with each individual operation:
double t0 = d * g;
double t1 = v * v;
double r = t0/t1;