lua "for" loop broken

Started by Rav3n_pl

Rav3n_pl Lv 1

code:
for i=1,10,1 do print(i) end
output: (…)7, 8, 9, 10

for i=0.1,1,0.1 do print(i) end
output: (…)0.7, 0.8, 0.9, 1

for i=0.1,1,0.01 do print(i) end
output: (…)0.97, 0.98, 0.99 !!!! NO 1 !!!

When step is 0.08 or lower it is not doing "final" count.

rmoretti Staff Lv 1

This isn't actually a bug in either lua or Foldit - it has to do with how real numbers are represented in computers. (Google "What Every Computer Scientist Should Know About Floating-Point Arithmetic")

The short answer is that just like 1/3 and 1/7 can't be exactly represented as a finite-length decimal, 1/10 can't be represented as a finite length value in the binary representation that computers use. When you write "0.01" in a computer program, the computer converts this to a binary number that is almost-but-not-quite equal to 0.01. (It also "helpfully" converts the almost-but-not-quite value back to the "simple" decimal representation when printing.) So when you add them together multiple times, the errors accumulate, and you don't actually hit 1.0 on the last time, but rather a number slightly higher, which then doesn't get printed.

You can test this by using a value that can be exactly converted to binary, e.g. 1/64 = 0.015625

for i=0,1,0.015625 do print(i) end
output: (…) 0.984375, 1

The work around is to stick with iterating over integers, which can be exactly converted to binary, and then do the division afterward. That way you don't get the accumulation of small errors:

for i=10,100,1 do print(i/100) end
output: (…) 0.97, 0.98, 0.99, 1

Rav3n_pl Lv 1

Use BCD then and forget about binary :P
(…)
Thats why in some langs "for" can be uses only on int variables… :)

NinjaGreg Lv 1

Note: in the last example, a workaround would be to set the for loop to use 1 to 100, then divide the value by 100 if you intend to use it in the body of the loop.