newLISP Fan Club

Forum => newLISP in the real world => Topic started by: newdep on September 05, 2007, 08:10:20 AM

Title: [Bug?] for step on float
Post by: newdep on September 05, 2007, 08:10:20 AM
Hi Lutz,



I dont understand the result below... do you have a clue?



Norman.







> (for (t 1 0.0 0.1) (println t))

1

0.9

0.8

0.7

0.6

0.5

0.4

0.3

0.2

0.1

-5.551115123e-17

-5.551115123e-17

>
Title:
Post by: cormullion on September 05, 2007, 08:15:42 AM
On my Mac it's


1
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0


so I expect your platform (Linux?) is giving you an optimistic view of zero!



And you know better than I do why you get it twice...! ;-)
Title:
Post by: newdep on September 05, 2007, 08:21:51 AM
Heee odd... seems to be a bug indeed... (linux newlisp 9.2.0 , 32 bits)





double screen vision, I have that also since yesterday evening ;-)
Title:
Post by: pjot on September 05, 2007, 08:24:16 AM
It may be the same bug with (sequence) mentioned before:



http://www.alh.net/newlisp/phpbb/viewtopic.php?t=1538&postdays=0&postorder=asc&start=25





Option [8].



Peter
Title:
Post by: newdep on September 05, 2007, 08:26:24 AM
..Thanks..



But unacceptable..

We are unable to ever reach 0.0 under linux using floats...  Handy ! ;-)
Title:
Post by: Lutz on September 05, 2007, 08:29:26 AM
yes, on Windows too, but fine on Mac OS X, other BSD's and Solaris. Use format to output the numbers.



Lutz



Ps: There is no precise way to convert from decimal to binary and back. On any OS you can find numbers showing remainders on division.
Title:
Post by: Lutz on September 05, 2007, 08:32:27 AM
when comparing floats you always should compare the difference of the numbers against some other small quantity. Google for: comparing floats



Lutz
Title:
Post by: newdep on September 05, 2007, 08:43:18 AM
Im realy lost...



Seems newlisp is simply "Ignoring" ZERO ;-)



> (setq t 1)

1

> (for (x 10 0) (println (dec 't 0.1)))

0.9

0.8

0.7

0.6

0.5

0.4

0.3

0.2

0.1

1.387778781e-16

-0.1

-0.1
Title:
Post by: Lutz on September 05, 2007, 09:02:47 AM
This is the same effect you where showing before. Again,  there is no precise way to convert between decimal to binary and back, use formatting when displaying.



Lutz
Title:
Post by: Lutz on September 05, 2007, 09:07:43 AM
for your last example there is a nice piece here:



http://www.petebecker.com/js/js200006.html



Lutz
Title:
Post by: newdep on September 05, 2007, 09:20:08 AM
..yes..yes i understand the issue.. ;-)



(for (x 1.0 0.01 0.01) (println x))



That assumes almost zero for my purpose ;-)



Thanks..



Norman.
Title:
Post by: Lutz on September 05, 2007, 10:19:50 AM
The difference between:


(for (i 1 10) (println (dec 'x 0.1)))

and


(for (i 1 0.0 0.1) (println i))

is, that newLISP when doing for loops and sequences tries to avoid accumulating the rounding error by calculating the total number of iterations first, then calculates the loop variable i as the product of 'step * count' and not as a repeated increment as in the first example. This way newLISP will never over/under run a loop, the way JavaScript would do, as shown in Peter Becker's article.



Your last example with decrementing x multiple times will produce the rounding error in pretty much any programming language after enough iterations depending on the floating point format and precision. Here the example in Python:


x = 1
for i in range(1, 11):
    x -= 0.1
    print x

0.9
...
0.1
1.38777878078e-16


Lutz



newLISP shows 1.387778781e-16 because it uses only 9 digits when displaying unformatted.
Title:
Post by: newdep on September 05, 2007, 02:12:15 PM
Ooo its very good that newlisp does NOT round it (visualy)

by default to 0.0 because that is even worse...



I understand the idea, no problem ..thanks for explaining..



Norman.