Re: Strange problem [message #28208 is a reply to message #28133] |
Mon, 26 November 2001 14:10   |
Andre Kyme
Messages: 19 Registered: September 2001
|
Junior Member |
|
|
Martin Downing wrote:
> Andre,
>
> Joshi is right, this behaviour is due to the lack of precision in
> floating point number representation. With your for loop
>
> for i=0., 0.801, 0.1 do print,i
>
> The code execution can more easily be visualised as
>
> i = 0.
> while i LE 0.8 do begin
> print, i
> i = i + 0.1
> endwhile
>
> Thus:
>
> IDL> for i=0., 0.8, 0.1 do print,i
> 0.000000
> 0.100000
> 0.200000
> 0.300000
> 0.400000
> 0.500000
> 0.600000
> 0.700000
>
> So what was the final value of i?
>
> IDL> print, i
> 0.800000
>
> Oh, isnt that the value of the upper bound?
>
> IDL> print, i EQ 0.8
> 0
> IDL> print, i - 0.8
> 5.96046e-008
>
> Clearly not! Slightly more than 0.1 was added each time, so there was a
> small excess to i when representing 0.8
>
> So the moral is that you have to be very careful when applying comparison
> operators to floating point numbers, one of which is implicitly applied in
> the FOR statement. Now you realise the problem, the answer is to be a little
> less strict with your comparisons. With FOR loops you can add a small
> excess, relative to the increment, to the upper bound:
>
> IDL> for i=0., 0.8001, 0.1 do print,i
> 0.000000
> 0.100000
> 0.200000
> 0.300000
> 0.400000
> 0.500000
> 0.600000
> 0.700000
> 0.800000
>
> Out of interest notice that the final value of "i" is now 0.9:
> IDL> print, i
> 0.900000
>
>> should i be worried?
> Well if you write code which depends on floating point numbers having
> perfect precision then yes!
> If you wanted to compare two floats for equality, you have to rethink what
> you mean by "equal", i.e. how exact does this application need the variables
> to be?
> Relying on doubles is not a robust solution, so instead of writing:
>
> IF a EQ b THEN ...
>
> write
>
> myPrecision = 0.001
> IF abs(a-b) LT myPrecision THEN ......
>
> I hope this helps
>
> Martin
Thanks Martin, that makes good sense. I can see the good reason for always
keeping your loop variable as an integer, so I'll make sure I do this from now
on.
Andre
|
|
|