spiccioni has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,
As a basic perl homework, I wrote the following script:
$n=0; print ($n,"\n"); while ($n<1){ $n=$n+.1; print ($n,"\n"); }
The output is:
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1
Since the while condition is that n should be less than 1, I don't understand why the loop is entered for a last time when the value of n is 1, so that the value 1.1. is printed.
Thanks for any illumination.
Sara

Replies are listed 'Best First'.
Re: non-integer increments
by fglock (Vicar) on Dec 02, 2004 at 15:50 UTC

    Because floating point is not exact (again)

    $n=0; print ($n,"\n"); while ($n<1){ $n=$n+.1; printf ("%0.18f \n", $n); }
    0 0.100000000000000006 0.200000000000000011 0.300000000000000044 0.400000000000000022 0.500000000000000000 0.599999999999999978 0.699999999999999956 0.799999999999999933 0.899999999999999911 0.999999999999999889 1.099999999999999867

    Each time you make a floating point addition, you are accumulating error.

Re: non-integer increments
by xorl (Deacon) on Dec 02, 2004 at 15:54 UTC
    Once again I learn something from someone else's question. Now I have a question of my own. Is there some way to easily deal with this problem?

      Yes, use an integer for the counter, and derive the floating point number from it. Integers are represented accurately and they don't accumulate error (unless they grow beyond a certain size).

      my $i=0; print($i, "\n"); while ($i < 10){ my $n = ++$i / 10; print($n, "\n"); }

      Update: oops, typo fixed.

        for (0..10) { print $n/10,"\n"; }
        ---
        demerphq

        just a small remark
        your probably meant
            $n = $i / 10;
        else you print out a few 0s
        si_lence