On Thu, 17 Jan 2008 rhubarbpie at poetworld.net wrote:

> I'm a Perl novice and hope this is a proper channel for a simple 
> question.  Why does the following decrement incorrectly below 10?  It 
> works with $i -- or $i -= .5.  This is part of a larger script and I've 
> made a workaround, but I'm still curious.

It has to do with the interpretation of ".1".  A computer will represent 
the number in binary digits.  Unfortunately for you, .1, unlike .5, 
doesn't have a short representation in binary digits.  The value .1 equals 
1/10 which equals 1/2 × 1/5.  In binary, multiplying by 1/2 is like 
multiplying by 1/10 in decimal, it just shifts everything one digit to the 
right of the point (is it still called a "decimal point" when it's in base 
2?).  So what is 1/5 in binary?

0.001100110011001100110011...

Which means that .1 is this:

0.0001100110011001100110011...

If we store 32 binary digits, we round it off like so:

0.00011001100110011001100110011001

which means we are off by 1.001100110011 × 2^-33 (where the first part of 
that is a binary representation), or in base 10: 1.2 × 2^-33 =
1.39698386192322... × 10^-10, so you'd expect to see errors in the 10th 
digit.

As someone else pointed out, different software and different 
architectures will use different numbers of binary digits to represent 
numbers so you will have different amounts of error in different 
situations.

Mike


> use Math::Complex;
>
> for ($i = 13; $i >= 1; $i -= .1) {
> print"$i\n";
> }
>
> 11
> 10.9
> 10.8
> 10.7
> 10.6
> 10.5
> 10.4
> 10.3
> 10.2
> 10.1
> 10
> 9.90000000000001
> 9.80000000000001
> 9.70000000000001
> 9.60000000000001
> 9.50000000000001
> 9.40000000000001
> 9.30000000000001
> 9.20000000000001
> 9.10000000000001
> 9.00000000000001
>
>
> _______________________________________________
> TCLUG Mailing List - Minneapolis/St. Paul, Minnesota
> tclug-list at mn-linux.org
> http://mailman.mn-linux.org/mailman/listinfo/tclug-list
>