http://www.perlmonks.org?node_id=863499

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

Hi, all: I'm getting a disturbingly-large discrepancy in running an identical script on different machines, and hoping that someone can suggest a cause and perhaps a fix. I'm suspecting a possible bug in my perl version.

Code being executed (@ARGV = qw/data.txt 636/):

#!/usr/bin/perl -w use strict; # Least square fit to quadratic function; input up to ~1k data pairs a +s space-separated columns. # # $Revision: 1.1 $ $Date: 2010-06-28 17:31:23-04 $ # $Source: /home/vogelke/notebook/2010/0628/polynomial-fit/RCS/pfit,v +$ # $UUID: 631e046d-f070-38bb-b287-bdd10b1d0efa $ # # John Lapeyre Tue Jan 28 18:45:19 MST 2003 # lapeyre@physics.arizona.edu # http://www.johnlapeyre.com/computers.html # http://www.johnlapeyre.com/pfit # # $Revision: 1.2 $ $Date: 2010-10-04 17:08:40-05 $ # Revised by Ben Okopnik # Added usage message, code strictures, input filtering/validation # # fit to A x^2 + B x + C # Works by solving matrix equation M.c = v. # c = (A,B,C) # v = (v1,v2,v3), where vn = \sum_i y_i x_i^(n-1) # m = ( (m4,m3,m2), (m3,m2,m1), (m2,m1,m0)) # where mn = \sum_i x_i^n die "Usage: ", $0 =~ /([^\/]+)$/, " <input_file> <target_number>\n" unless @ARGV == 2; my $tgt = pop; my ($m0, $v1, $v2, $v3, $m1, $m2, $m3, $m4, $d, @x, @y) = 0; while (<>) { next unless /^\s*(\d+)(?:$|\s+(\d+)\s*$)/; push @y, $+; push @x, defined $2 ? $1 : $m0; $m0++; } die "Badly-formatted data (one or two numerical columns required)\n" unless $m0; for (0 .. $#x) { my $x = $x[$_]; my $y = $y[$_]; $v1 += $y * $x**2; $v2 += $y * $x; $v3 += $y; $m1 += $x; $m2 += $x * $x; $m3 += $x**3; $m4 += $x**4; } # Used mathematica to invert the matrix and translated to perl $d = $m2**3 + $m0 * $m3**2 + $m1**2 * $m4 - $m2 * (2 * $m1 * $m3 + $m0 + * $m4); my $A = ($m1**2 * $v1 - $m0 * $m2 * $v1 + $m0 * $m3 * $v2 + $m2**2 * $ +v3 - $m1 * ($m2 * $v2 + $m3 * $v3)) / $d; my $B = (-($m1 * $m2 * $v1) + $m0 * $m3 * $v1 + $m2**2 * $v2 - $m0 * $ +m4 * $v2 - $m2 * $m3 * $v3 + $m1 * $m4 * $v3) / $d; my $C = ($m2**2 * $v1 - $m1 * $m3 * $v1 + $m1 * $m4 * $v2 + $m3**2 * $ +v3 - $m2 * ($m3 * $v2 + $m4 * $v3)) / $d; # A x^2 + B x + C printf "%f\t%f\t%f\n", $A, $B, $C; # Correct $C for final value $C -= $tgt; # PE solver my $y1 = (-$B + sqrt($B**2 - 4 * $A * $C)) / (2 * $A); my $y2 = (-$B - sqrt($B**2 - 4 * $A * $C)) / (2 * $A); printf "Roots: %.3f or %.3f\n\n", $y1, $y2;

The data being processed (CO2 measurements at Mauna Loa):

1962 318 1982 341 2002 373

The results:

# i686 running Linux with perl-5.10.0 0.011256 -43.244877 41833.442623 Roots: 2093.870 or 1747.905 # IBM x3400 running Linux with perl-5.10.1 0.011250 -43.220086 41809.478563 Roots: 2083.912 or 1757.866 # Sparc running Solaris-10 with perl-5.10.1 0.011250 -43.220086 41809.478563 Roots: 2083.912 or 1757.866 # After adding "use bignum;" on either of the last two 0.011250 -43.220000 41809.395000 Roots: 2083.912 or 1757.866

Any help or suggestions would be appreciated.


--
"Language shapes the way we think, and determines what we can think about."
-- B. L. Whorf