Seekers of Perl Wisdom provide us with a steady diet of questions about why arithmetic in Perl sometimes doesn't "add up" as expected, and PM's wisdom providers get regular exercise explaining how floating point arithmetic is inherently limited in precision.

But as I was playing with some code in Snippets (file/language entropy calculator), I was surprised to find that the precision limits seem to vary from one run to the next -- or rather, the behavior of floating-point arithmetic beyond the precision limit was not constant, as I would have expected.

Both the OP's code in that Snippet thread and my trimmed-down version of same seem to produce different values on successive runs over the same input text file. Here are a few sample output values from repeating the same computation on the same input (this is running on a G4 powerbook with macosx 10.3.6, Darwin kernel version 7.6.0, perl v5.8.1-RC3 built for darwin-thread-multi-2level):

5.35423847163199795318 5.35423847163199884136 5.35423847163199972954 5.35423847163200150590 5.35423847163200239407
and if I run it more times, I get more distinct values.

Now, it's obvious that no one should be paying attention to more than 12 or 13 digits in terms of floating-point accuracy (so wufnik should adjust his ideas about "printf" formatting), but I'm wondering whether this variability is observed on other systems.

I did take the time to check the same code and data on solaris/sparc (perl 5.5.3) and freebsd (i386 and amd64, perl 5.8.5) -- none of them showed variable behavior like I saw on the mac (solaris/sparc always came up with one answer, which happened to match one of the answers on the mac; the i386 and amd64 freebsd's both came with a consistent single answer every time, which differed from the sparc answer and matched another of the mac's results).

So it smells like a mac/G4 issue, rather than a perl issue. But it struck me as noteworthy, and I'd be interested in others' reactions.

Replies are listed 'Best First'.
Re: Floating point (in)accuracy: more "interesting" than expected
by hossman (Prior) on Dec 11, 2004 at 20:03 UTC

    I think the descrepencies you are seeing have nothing to do with floating point accuracy, and everything to do with hash seed randomization.

    As I understand it, in older versions of perl, the hashing algorithm was (somewhat) deterministic, making it possible to "predict" things -- which is not so good for security. circa perl 5.8.1, the hasing algorithm was changed so as to be non-deterministic. ie: every time you run your app, you get a slightly different hashing seed

    Which means: every time you run your app, even on identicle input, hashes you build will be slightly different, and the order the elements come back (from either keys or values) will be different. So the second time you execute your app, and loop over the output of values and do incrimental floating point calculations -- you are doing slightly different calculations the the first time you executed the app.

    I can't confirm any of this, because I don't have access more then one version of perl right now, but i believe that if you use "sort values" instead of "values" you'll get a deterministic result on any version of perl

      Good catch! When I added "sort" into the loop over values, the mac/perl-5.8.1 runs came out with the same answer every time.

      But now that leaves me wondering about freebsd/perl-5.8.5 on the i386 and amd64 machines I tried: why would they always give the same answer, if they're supposed to share 5.8.1's non-deterministic hashing method... Could they actually be that much more accurate?

        Well, there are two possibilities i can think of...

        1. Note that the 5.8.2 perldelta indicates some tweaks were made again. I'm not sure what they were, but maybe they reduced some of the percieved randomness of ordering returned by "values" while keeping the security.
        2. It's possible that your deterministic versions of perl were compiled with "USE_HASH_SEED_EXPLICIT" set, or perhaps you have the "PERL_HASH_SEED" enironment variable set. see INSTALL for more info
Re: Floating point (in)accuracy: more "interesting" than expected
by dwhite20899 (Friar) on Dec 13, 2004 at 13:41 UTC
    FYI...
    # dwhite@nist.gov 3/23/04 - based on BASIC code # in "Astronomical Algorithms" 2nd ed. by Jean Meeus, # pg 17-19 # start of code block 1 $x = 1 ; $j = 0 ; $x *= 2 ; print "Testing significant bits, significant digits...\n"; while (($x + 1) != $x) { print "\t$j\t$x\n"; $j++ ; $x *= 2 ; } print "\t$j\t$x\n"; print "\n", $j , " significant bits in mantissa of floating number\n" +, int($j * 0.30103) , " significant digits in a decimal number (", $j + * 0.30103 , ")\n above is only for SIMPLE ARITHMETICS, not trig func +tions!\n"; # end of code block 1 print "\nthe 2nd column here should NOT list diverging numbers...\n"; print "\$x=1.0/3.0; for(\$j=1;\$j<31;\$j++) { \$x = (9*\$x+1)*\$x-1 ; }\n"; # start of code block 2 $x = 1.0/3.0 ; for($j=1;$j<31;$j++) { $x = (9*$x+1)*$x-1 ; # print "$j\t$x\n"; # for details if ($j % 6 == 1) { print "$j\t$x\n"; } } print "However, they probably will diverge on your machine.\n"; # end of code block 2
Re: Floating point (in)accuracy: more "interesting" than expected
by sauoq (Abbot) on Dec 15, 2004 at 05:31 UTC

    Well, you think that's something?! My G4 cube occasionally turns itself on and off...

    No, this isn't a lame attempt at a joke. This is actually a known problem apparently with the power buttons which aren't buttons at all but little sensors that recognize a change in capacitance when your finger is over them. Apple would fix my machine, but I got it second hand (for free) and I'm not inclined to pay to have the old thing fixed - nice 17 inch cinema display or not.

    -sauoq
    "My two cents aren't worth a dime.";