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

Hi,
I'm running a recent version of Cygwin (3 or 4 months old) and the perl that came with it (version 5.8.7). I am surprised by this:
Rob@desktop ~/pscrpt $ perl -MDevel::Peek -e "Dump(2 ** 43 + 12345);" SV = IV(0x4e9908) at 0x4d0f80 REFCNT = 1 FLAGS = (PADBUSY,PADTMP,IOK,READONLY,pIOK) IV = 8796093034553
I expected something like:
SV = NV(0x8a1fd4) at 0x3f51d4 REFCNT = 1 FLAGS = (PADBUSY,PADTMP,NOK,READONLY,pNOK) NV = 8796093034553
which is what I get on linux and native Win32 perls 5.8.8 (and earlier). Actually, linux doesn't set the PADBUSY or PADTMP flags, but I'm not concerned with that.

Is that Cygwin representation acceptable ?
I'm thinking it's unacceptable to put, into the IV slot, an integer that's too large for the 'long' type to handle. And shouldn't it be declaring itself as an 'NV' and setting the 'NOK' flag instead of 'IOK' ?
What are the rules regarding this (if there are any) ?

Also, is this some special Cygwin feature that the Cygwin developers have implemented by modifying the perl source - or would I find exactly the same behaviour if I built perl on Cygwin using official perl source ? (That question's a bit OT - if no-one here knows the answer I'll take more appropriate steps to find out.)

Cheers,
Rob

Replies are listed 'Best First'.
Re: Cygwin perl and (internal) numeric representations.
by parv (Parson) on Nov 26, 2006 at 03:52 UTC

    Here is what i get on FreeBSD/i386 6.2-PRERELEASE ...

    SV = IV(0x806d1a4) at 0x804e224 REFCNT = 1 FLAGS = (IOK,READONLY,pIOK) IV = 8796093034553

    Then again perl has been compiled with -Duse64bitint if that makes any difference.

      Then again perl has been compiled with -Duse64bitint if that makes any difference.

      Yes ... it probably does make a difference. I had missed that Cygwin's perl was also compiled with use64bitint.

      Does it make sense to build perl with use64bitint, for a 32-bit machine, with $Config{longsize} set to 4 ? My Cygwin perl certainly isn't giving me 64-bit int handling capability. As with my other perls, only integers up to 53 bits can be handled accurately.

      Anyway, my problem is that the following xs code is not portable:
      long i; if(SvIOK(a)) i = SvIV(a);
      On my Cygwin perl I need to:
      double d; if(SvIOK(a)) d = SvNV(a);
      or perhaps (untested):
      long long ii; if(SvIOK(a)) ii = (long long)SvIV(a);
      I guess I just need to rethink what I'm trying to do.

      Thanks parv.

      Cheers,
      Rob

        Happy to help, Rob, not that I could help with your XS problem.

        As to your question about using 64-bit integers on 32-bit machine, well that allows to exceed 2**32 :) (or, create situations like yours). Speaking of which ... a small thread on Google.