Code acts as if z
was a double
and y/(float)100000.0
is y/100000.0
.
float x = 1028.25478;
long int y = 102825478;
double z = y/100000.0;
// output
x = 1028.254761 z = 1028.254780
An important consideration is FLT_EVAL_METHOD
. This allows select floating point code to evaluate at higher precision.
#include <float.h>
#include <stdio.h>
printf("FLT_EVAL_METHOD %d\n", FLT_EVAL_METHOD);
Except for assignment and cast ..., the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type. The use of evaluation formats is characterized by the implementation-defined value of FLT_EVAL_METHOD
.
-1
indeterminable;
0
evaluate all operations and constants just to the range and precision of the
type;
1
evaluate ... type float
and double
to the
range and precision of the double
type, evaluate long double
... to the range and precision of the long double
type;
2
evaluate all ... to the range and precision of the
long double
type.
Yet this does not apply as z
with float z = y/(float)100000.0;
should lose all higher precision on the assignment.
I agree with @Antti Haapala that code is using a speed optimization that has less adherence to the expected rules of floating point math.