Mail Archives: djgpp/1996/12/03/04:58:35
On Sat, 30 Nov 1996 14:05:17 GMT, Francois Charton
<deef AT pobox DOT oleane DOT com> wrote:
>float f;
>int i,j;
>i=(int) (1.13*100.0);
>f=1.13*100.0;
>j=(int) f;
>printf("%d %d\n",i,j);
>
>
>prints 112 113...
>
>And this is not because you don't have a FPU : I got a 486DX.
>I'd say this is a parsing problem, with the way DJGPP represents
>internally floating point numbers :
I don't think this is quite correct... It's not a parsing problem, and
it's not DJGPP's (or gcc's) fault. I think it's more a problem with
converting binary floating point into decimal, combined with a lack of
understanding of the cast from float to int.
Last things first: the cast from float to int does not round the
number; it just returns the greatest integer smaller than the argument
(like floor(x)). Consequently, (int)112.9999999... = 112, not 113. If
you want 'standard' rounding, add 0.5 before casting.
And the main problem (I think...): Base conversions of floating point
numbers cannot always come out correctly - in fact they rarely do. As
an example, consider base 3 and base 10. We will convert from base 3
to base 10...
Calculation base 3 base 10
y = 1/3 0.1 0.333333333
x = y*3 0.1 * 10 0.333333333 * 3
= 1 1 0.999999999
floor(x) 1 0
I can't really explain this in words... It is unavoidable. What you
are seeing with 112 vs 113 is a similar problem, but between decimal
and binary.
Bear in mind that floats and doubles are only approximations; their
resolution is limited. If you take care to round 'correctly' by adding
0.5, as mentioned above, you should be okay. Elsewhere in this thread,
I think, a macro has been suggested:
#define _round(x) ((int)(floor((x)+0.5)))
or something similar - possibly without the floor... it isn't strictly
necessary since it's implicit in the cast. Whether it's good practise
to include it or not, and whether it's optimized out of the final
code, I don't know...
George Foot
- Raw text -