XP is just a number PerlMonks

### Is this odd behavior a floating point problem?

by wickedjester (Initiate)
 on Mar 23, 2012 at 16:58 UTC Need Help??

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

Hello!

I've got an array with 40 elements with each element having a value of '0.001'. If I add them all together and divide by 40 to get the average, I get something like:

\$Avg = 0.001025

rather than 0.001, which is what it should really return.

Now, the script I'm righting is a chemical diffusion model dealing with very small numbers and this kind of inaccuracy is causing me problems. If this is a floating point issue, can anyone give me a recommendation on how to deal with this?

Many thanks!

• Comment on Is this odd behavior a floating point problem?

Replies are listed 'Best First'.
Re: Is this odd behavior a floating point problem?
by Eliya (Vicar) on Mar 23, 2012 at 17:14 UTC

For reasons described in excruciating detail in the document already cited, there will be errors, but according to a quick test on my system, they are nowhere near as large as you claim:

```\$ perl -e '\$x=0.001; \$sum += \$x for 1..40; printf "%.20f", \$sum/40'
0.00100000000000000067

Looks more like a "one off" error to me (i.e. summing over one more than you divide by):

```\$ perl -e '\$x=0.001; \$sum += \$x for 0..40; printf "%.20f", \$sum/40'
0.00102500000000000074

:D Looks like two separate off-by-one error (OBOE) errors to me :)

In short

```perl -MData::Dump -e " @f = map { 0.001 } 1 .. 40; dd\@f; \$o = 0; for(
+@f){ dd \$o+=\$_; } dd int @f; dd \$o/int(@f); "

perl -MData::Dump -e "  \$o = 0; for(1 .. 40){ dd \$o+= 0.001; } dd \$o/4
+0; "

It didn't dawn on me to check wickedjesters (or your) math until ww raised the quesiton

Not sure what you're talking about.

n times adding x to zero is mathematically (but not necessarily numerically) the same as n * x.

```\$ perl -le '\$sum += 1 for 1..40; print \$sum'
40

So where is the problem?  I think you overlooked that \$sum is initially undef/zero.

Re: Is this odd behavior a floating point problem?
by roboticus (Chancellor) on Mar 23, 2012 at 17:25 UTC

You don't show your code, but I'm pretty sure you're not doing what you think you're doing. Specifically, I believe you're adding 41 copies of 0.001, as that's the only way I can reproduce your results:

```\$ cat t.pl
#!/usr/bin/perl
my @a = (0.001) x 41;
my \$sum=0;
\$sum += \$_ for @a;
print "Avg: ", \$sum/40, "\n";

\$ perl t.pl
Avg: 0.001025

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Re: Is this odd behavior a floating point problem?
by Anonymous Monk on Mar 23, 2012 at 17:02 UTC
A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Is this odd behavior a floating point problem?
by toolic (Bishop) on Mar 23, 2012 at 17:29 UTC
• sprintf
• perlfaq4 Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?
Re: Is this odd behavior a floating point problem?
by Khen1950fx (Canon) on Mar 23, 2012 at 19:18 UTC
As I see it, you're performing addition, division, and averaging. You can dispense with the addition, division, and since you have an array, just do an average of the elements.
```#!/usr/bin/perl -l

use strict;
use warnings;
use Array::Average;

print average(
0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
);
Returns: 0.001
You can dispense with the addition, division,...

And how do you think the module arrives at its result?  What it does is exactly addition and division — which of course suffers from the same floating point issues.  Here's the relevant code snippet:

```  if (@data) {
my \$sum=0;
\$sum+=\$_ foreach @data;
return \$sum/scalar(@data);
} else {
return undef;
}

Anyhow, as has already been pointed out, the OP's problem has likely nothing whatsoever to do with those general floating point issues, but is presumably simply the result of having computed the sum incorrectly.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://961262]
Approved by lidden
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2024-09-20 20:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
The PerlMonks site front end has:

Results (26 votes). Check out past polls.

Notices?
 • erzuuli ‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.