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

I am trying to step through a set of values by an increment less than 1. Simplified version of my code looks like this:
my $i = 0.1; my $v = 0 - $i; while ( $v < 9 ) { $v += $i; print $v, $/; }
I was expecting the value to step up 0, 0.1, 0.2, ... 0.9, 1, 1.1, ... 8.9, 9. And it does, right up to 5.9. But then 5.9 is followed by 5.99999999999999, and the long series of 9s continues for the remainder of the sequence (that is, next is 6.09999999999999, 6.19999999999999, 6.29999999999999, and so on)

This is not expected. Can anybody explain why it's doing this and how I could make it not?

I'm running Perl 5.18.2 on a Mac (Sierra OS). And no, upgrading to a different Perl build is not an acceptable solution unless this is a well known bug in that particular release. Even then, I probably have to code around the bug.

Replies are listed 'Best First'.
Re: Decimal Increment Bug?
by toolic (Bishop) on Mar 16, 2018 at 19:28 UTC
Re: Decimal Increment Bug?
by pryrt (Monsignor) on Mar 16, 2018 at 19:30 UTC
Re: Decimal Increment Bug?
by ikegami (Patriarch) on Mar 16, 2018 at 23:43 UTC

    1/10 is a periodic number in binary, just like 1/3 is a periodic number in decimal. As such, it can't be accurately stored as a floating-point number.

    First, reduce the accumulation of error through the use of integers.

    Secondly, use rounding or a tolerance when appropriate.

    for my $i (0..89) { my $v = $i / 10; printf "%.1f\n", $v; }

    (Because we avoided the accumulation of error, the rounding isn't actually needed here.)

A reply falls below the community's threshold of quality. You may see it by logging in.