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

Hi,

The powerpc long double (double-double) can be a bit of a bitch, but you've just got to love this aspect of it (on Debian wheezy, perl-5.18.1, built with -Duselongdouble, gcc-4.6.3):
$ perl -le 'print "ok" if 1.0 + 5e-200 != 1.0;' ok
Are there any other processors providing such discernment ?
Are there any compiler tricks that will enable the building of a perl (on an otherwise non-accommodating machine) that provides such discernment ?

Cheers,
Rob

Replies are listed 'Best First'.
Re: powerpc double-double arithmetic
by Athanasius (Archbishop) on Oct 10, 2013 at 03:13 UTC
    Are there any compiler tricks that will enable the building of a perl (on an otherwise non-accommodating machine) that provides such discernment ?

    I don’t know; but for the benefit of newbies reading this thread, I just want to point out that this level of discernment (and more) is already available out-of-the-box on any (non-ancient) perl via the bignum pragma:

    13:07 >perl -wE "say 'ok' if 1.0 + 5e-200 != 1.0;" 13:07 >perl -Mbignum -wE "say 'ok' if 1.0 + 5e-200 != 1.0;" ok 13:07 >perl -wE "say 'ok' if 1.1 + 5e-200 != 1.1;" 13:07 >perl -Mbignum -wE "say 'ok' if 1.1 + 5e-200 != 1.1;" ok 13:07 >perl -v This is perl, v5.10.1 (*) built for MSWin32-x86-multi-thread ... 13:07 >

    But no doubt the -Duselongdouble version is more efficient.

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: powerpc double-double arithmetic
by johngg (Canon) on Oct 09, 2013 at 14:18 UTC

    I'm not sure as I no longer have access to a SPARC machine to test. However, I do recall that sizeof() applied to a long double on the SPARC architecture showed that it used 16 bytes whereas a long double on x86_64 used only 12 bytes. This might imply increased precision on SPARC boxes, perhaps another Monk will have the access to test it out.

    Cheers,

    JohnGG

      This might imply increased precision on SPARC boxes

      In many instances the 16 byte long double provides the same (64-bit) precision as the 12 byte variant ... and the same exponent range, too, I think.

      But it's the double-double arrangement that enables contrived comparisons (such as the one I provided) to work.
      It would take a data type providing 663 bits of precision to detect that 1.0 + 5e-200 > 1.0, whereas the double-double arrangement of the PowerPC long double stores 1.0 in one double and 5e-200 in the other. The processor then knows that the sum of both is greater than either of the 2 doubles because both doubles are positive and non-zero.
      At least, that's how I surmise.

      The processor cannot detect that 1.1 + 5e-200 > 1.1 because the "1.1" value gets written over both doubles - and adding 5e-200 then makes no difference to the 2 stored double values.

      I was hoping that a printf "%.200Le", ... of the 1.0 + 5e-200 value might print out the actual value of 1.00000...005 but, alas, doesn't even get close (in perl or C).

      BTW, the "bitch" part is that, with certain values, you can get rounding errors if you try to print out more than 15 decimal digits of precision (in perl or C).

      All in all, an intriguing arrangement - and one that almost works beautifully.

      Cheers,
      Rob
        From what I know about the x86 long double is that, for PPC, I guess sizeof is returning 16 for alignment reasons. 12 is the actual used portion. A long double is 80 bits/10 bytes on x86. Mingw claims it is 12 bytes in a sizeof.