lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2015-10-29 19:16 GMT+02:00 iain morland <iain@iainmorland.net>:

> If I assign a variable to the result of 23.2/0.2, and print that variable,
> Lua outputs 116.
>
> However if I then use the same variable as the limit in an iterator,
> the iterator stops on the 115th repeat, rather than the 116th as
> expected.
>
> So it therefore seems that the variable is a floating point number
> between 115 and 116.
>
> I don’t understand why I can’t print the floating point value of this
> variable. I haven’t rounded or truncated it, so why does it print
> exactly 116, even though that’s not its value?

Floating point arithmetic is very complicated from a mathematical
point of view. Only two of the standard laws (commutative addition
and commutative subtraction) are valid; all the others (associative
addition, associative subtraction, distributive addition over
multiplication, distributive multiplication over addition) may fail.

In particular, it may not be true that a+a+a ... + a (with n addends)
equals a*n, and you cannot predict in advance whether the
answer is <=a*n or >=a*n.

Moral: never use floating point in an arithmetic 'for' unless you
are sure that the comparison will not be close. For example:

for k=0.2,23,0.5 do -- perfectly OK, k goes from 22.7 to 23.2

for k=0.2,23,0.2 do -- not OK, k goes from 22.8 to 23±? to 23.2

for k=0.2,23.1,0.2 do -- OK, k goes from 23.0 to 2 to 23.2

As the last example suggests, adding half the step size to the
limit is the failsafe workaround when the limit is an exact
multiple of the step sze away from the starting value.