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

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

I tried to create a greeting appropriate for the day:
perl -e'print pack q/d*/,(1.7453026326120991e+194,1.5156845462257262e- +147)'

For me (Ubuntu 9.10 64 bit, perl 5.10.0) this prints... well, you can guess what.

But for others, it prints "Kerry Chtistmas!".

What's the reason for this difference? Is it that my system is 64 bit while theirs is probably 32 bit?

Replies are listed 'Best First'.
Re: What does this print for you?
by BrowserUk (Patriarch) on Dec 24, 2009 at 23:18 UTC

    Works under Vista with both 32-bit 5.8.9 & 64-bit 5.10.1

    [23:06:10.70] c:\test>\perl32\bin\perl.exe -e"print pack q/d*/,(1.7453 +026326120991e+194,1.5156845462257262e-147)" Merry Christmas! [23:06:43.10] c:\test>\perl64\bin\perl.exe -e"print pack q/d*/,(1.7453 +026326120991e+194,1.5156845462257262e-147)" Merry Christmas!

    A possible difference is their hardware uses a different double-precision float native format.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: What does this print for you?
by ikegami (Patriarch) on Dec 25, 2009 at 06:40 UTC

    The difference is tiny, numerically speaking. Specifically, it's a variation in the second least significant bit.

    Merry Ch 684320797272654D = 1.320797272654D * 2**645 Kerry Ch 684320797272654B = 1.320797272654B * 2**645 ristmas! 2173616D74736972 = 1.3616D74736972 * 2**(-488) tistmas! 2173616D74736974 = 1.3616D74736974 * 2**(-488)
Re: What does this print for you?
by JadeNB (Chaplain) on Dec 24, 2009 at 22:57 UTC
    I'm no pack expert, but I do happen to have otherwise-identical installs of perl (version 5.8.9) from MacPorts on a 32-bit PPC running Mac OS X.4.10, and a 64-bit Intel machine running Mac OS X.5.8:
    $ perl -e'print pack q/d*/,(1.7453026326120991e+194,1.5156845462257262 +e-147)' hC yrreM!samtsir
    (on the 32-bit machine) and
    $ perl -e'print pack q/d*/,(1.7453026326120991e+194,1.5156845462257262 +e-147)' Merry Christmas!
    (on the 64-bit machine). I'm not seeing a spurious ‘K’ or ‘t’, but I am seeing an unexpected reversal—and, hey, the PPC uses a different endian-ness from the Intel ….
      I can see where the reversal comes from, if the PPC indeed runs in an opposite* endian mode from the Intel.

      However, I understand even less where the difference mentioned in the OP comes from.
      On my 32 bit Vista virtual machine it prints "Kerry Cthistmas!", but windows users in this thread reported that their windows perl prints the correct message.

      Perhaps the perl compile-time flags give a clue into this mistery?
      The 64 bit Ubuntu 9.10, perl 5.10.0 version:
      MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API

      The 32 bit Vista perl 5.10.0 (Camelbox build) version:
      MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS USE_LARGE_FILES USE_PERLIO

      * I always found this endian business a horrible mess - especially that there are certain combinations of CPUs, OSes and compilers where mixed endianness occurs.

        The I-guess relevant portion of the output of perl -V is

        hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultipl +icity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef
        on the 64-bit machine. I'll edit this comment from my 32-bit machine in a few minutes.

        UPDATE: Here's the same passage from my 32-bit machine:

        hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultipl +icity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef
        but maybe it's this bit that's more interesting:
        Compile-time options: PERL_MALLOC_WRAP USE_FAST_STDIO USE_LARGE_FILE +S USE_PERLIO

Re: What does this print for you?
by Marshall (Canon) on Dec 24, 2009 at 23:03 UTC
    #!/usr/bin/perl -w use strict; print pack q/d*/,(1.7453026326120991e+194,1.5156845462257262e-147); __END__ Prints: Merry Christmas! on ActiveState 5.10, Windows XP, 32 bit Perl 5.10 Completely unexpected result, but that is what it does. Note: C:\TEMP>perl -e 'print pack q/d*/,(1.7453026326120991e+194,1.515684546 +2257262e-147)' Can't find string terminator "'" anywhere before EOF at -e line 1. The Windows syntax is: C:\TEMP>perl -e "print pack q/d*/,(1.7453026326120991e+194,1.515684546 +2257262e-147)" Merry Christmas!
Re: What does this print for you?
by kikuchiyo (Hermit) on Dec 25, 2009 at 10:32 UTC
    Thank you all for your answers.

    I used this floating point converter to generate my numbers: http://babbage.cs.qc.edu/IEEE-754/

    I simply reversed the characters in "Merry Ch" and "ristmas!" and fed the hex equivalents into the converter. However, I had to adjust them a bit to make the script actually print Merry Christmas!.

    Now if we assume the converter to be conformant to IEEE-754, then it follows that your Perl (or compiler or OS) is not conformant, if it prints "Merry Christmas!" Even if it is a small difference numerically, it is a difference.

    Anyway, I wish you all a merry Christmas, regardless the correctness of your floating point library. :)
Re: What does this print for you?
by Anonymous Monk on Dec 24, 2009 at 22:47 UTC
    It goes fine for me on Windows XP 32bits and prints "Meryy Christmas!"
Re: What does this print for you?
by kikuchiyo (Hermit) on Dec 25, 2009 at 20:56 UTC
    I also tried this:

    #!/usr/bin/perl use strict; use warnings; use Inline C => 'DATA'; print "Perl native:\n"; print pack q/d*/, (1.7453026326120991e+194, 1.5156845462257262e-147); print "\n\n"; print "Defined in C function:\n"; print pack q/d*/, ( getx(), gety() ); print "\n"; __DATA__ __C__ double getx () { static double x = 1.7453026326120991e+194; return x; } double gety () { static double y = 1.5156845462257262e-147; return y; }

    Result:

    Perl native: Merry Christmas! Defined in C function: Kerry Chtistmas!
Re: What does this print for you?
by Kirsle (Pilgrim) on Dec 25, 2009 at 03:38 UTC
    $ perl use strict; print pack q/d*/,(1.7453026326120991e+194,1.5156845462257262e-147); __END__ Kerry Chtistmas!
    Fedora 12 i686, perl-5.10.0-82.fc12.i686
Re: What does this print for you?
by eye (Chaplain) on Dec 25, 2009 at 03:48 UTC
    Doesn't Perl also use the operating system's math libraries? That may be another source of variation.
      You must be thinking of the C library. It's used to parse numbers, for one. Different compilers, different libraries.
Re: What does this print for you?
by rowdog (Curate) on Dec 25, 2009 at 19:47 UTC

    My 64 bit Arch Linux works right but my wife's 32 bit Ubuntu was wrong so I fired up VirtualBox to test some other 32 bit systems. Arch, Debian, and WinXP (Strawberry) all did the wrong thing. Then, to my suprise, FreeBSD 8.0 did the right thing. I noticed that FreeBSD used use64bitint=define while the other 32 bit perls didn't.

    Aha! So I compiled perl with ./Configure -Duse64bitint on the Debian virtual machine ... nope, Kerry Chtistmas!

    The common factor for Linux appears to be 32 bit glibc. I suspect Strawberry also uses glibc while FreeBSD does not.

    I went back and compiled a perl without -Duse64bitint on FreeBSD: Merry Christmas!

    readmore to see my FreeBSD perl -V

    Edit: I was wrong about Strawberry using glibc. I also added the last FreeBSD paragraph.
      strawberry does not use glibc
      $ perl -V:.+|grep -i libc d_gnulibc='undef'; gnulibc_version=''; libc='-lmsvcrt';

        Indeed, I stand corrected.

Re: What does this print for you?
by Anonymous Monk on Dec 25, 2009 at 10:44 UTC
    $ C:\strawberry\perl\bin\perl.exe -e " print pack q/d*/,(1.7453026326 +120991e+194,1.5156845462257262e-147) Kerry Chtistmas!
    and ActivePerl
    $ C:\Perl\bin\perl.exe -e " print pack q/d*/,(1.7453026326120991e+194 +,1.5156845462257262e-147) " Merry Christmas!
Re: What does this print for you?
by shmem (Chancellor) on Dec 29, 2009 at 08:14 UTC

    Hm...

    qwurx [shmem] ~ > perl -le'print pack q/d*/,(1.7453026326120991e+194,1 +.5156845462257262e-147)' Kerry Chtistmas! qwurx [shmem] ~ > perl -le'print pack q/d*/,(1.7453026326120998e+194,1 +.5156845462257258e-147)' Merry Christmas!

    For me, the conversion of 1.7453026326120991e+194 yields 684320797272654B, which is

    perl -le '$_=pop;print map{chr hex} reverse /(..)/g' 684320797272654B Kerry Ch