0

Possible Duplicates:
Why is floating point arithmetic in C# imprecise?
Why does ghci say that 1.1 + 1.1 + 1.1 > 3.3 is True?

#!/usr/bin/perl
$l1 = "0+0.590580+0.583742+0.579787+0.564928+0.504538+0.459805+0.433273+0.384211+0.3035810";
$l2 = "0+0.590580+0.583742+0.579788+0.564928+0.504538+0.459805+0.433272+0.384211+0.3035810";
$val1 = eval ($l1);
$val2 = eval ($l2);
$diff = (($val1 - $val2)/$val1)*100;
print " (($val1 - $val2)/$val1)*100 ==> $diff\n";

Surprisingly the output ended up to be

((4.404445 - 4.404445)/4.404445)*100 ==> -2.01655014354845e-14.

Is it not supposed to be a ZERO???? Can any one explain this please......

2
  • 3
    What, you don't think that 0.000000000000201655014354845 is close enough to zero? Commented Jan 17, 2010 at 17:50
  • This question isn't completely a duplicate of the cited non-perl questions because the question is complicated by perl providing a default stringification precision of slightly less than the available numeric precision. Commented Jan 18, 2010 at 6:39

4 Answers 4

19

What every computer scientist should know about floating point arithmetic

See Why is floating point arithmetic in C# imprecise?

This isn't Perl related, but floating point related.

Sign up to request clarification or add additional context in comments.

Comments

7

It's pretty close to zero, which is what I'd expect.

Why's it supposed to be zero? 0.579787 != 0.579788 and 0.433273 != 0.433272. It's likely that none of these have an exact floating point representation so you should expect some inaccuracies.

Comments

4

From perlfaq4's answer to Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?:


Internally, your computer represents floating-point numbers in binary. Digital (as in powers of two) computers cannot store all numbers exactly. Some real numbers lose precision in the process. This is a problem with how computers store numbers and affects all computer languages, not just Perl.

perlnumber shows the gory details of number representations and conversions.

To limit the number of decimal places in your numbers, you can use the printf or sprintf function. See the "Floating Point Arithmetic" for more details.

printf "%.2f", 10/3;

my $number = sprintf "%.2f", 10/3;

1 Comment

This is kind of the flip side of that perlfaq; see my comment to the question.
3

When you change the two strings to be equal (there are 2 digits different between $l1 and $l2) it does indeed result in zero.

What it is demonstrating is that you can create 2 different floating point numbers ($val1 and $val2) that look the same when printed out, but internally have a tiny difference. These differences can be magnified up if you're not careful.

Vinko Vrsalovic posted some good links to explain why.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.