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

What's the right way to specify a "long long" (aka signed 64-bit int) in an XS typemap file for a 32-bit Perl? I've found it varyingly declared as:

Specifically, I'm trying to get this bit of XS to work with a stock Apple-provided Perl for a QuickTime utility function:

QTTime QTMakeTime(timeValue, timeScale) long long timeValue long timeScale

(Side note: a good way to phrase this search in google is: site:search.cpan.org "long long" inurl:typemap)

Update: To summarize the thread, there is no right way, but there are a bunch of possible hacks.

Replies are listed 'Best First'.
Re: Supporting long long types in XS
by Joost (Canon) on Nov 21, 2006 at 17:53 UTC
    I don't think a 32 bit perl has a direct equivalent of 64 bit integers. That probably means you can do 3 things:

    1. Use a 32 bit int (i.e. T_IV or T_UV) which has the advantage that any numbers in the 32 bit range can be accurately be represented, but higher numbers cannot be represented at all.

    2. Use a floating point number (i.e. T_NV, which is an 8-bitbyte double on my system) which is able to represent the whole range, but not 100% accurately.

    3. Create your own type conversion from/to a perl object (i.e. an XS pointer to a long long, in which case you need to provide some mechanism for read/write access, or maybe you can convert from/to Math::BigInt). Probably the most hassle, but you can guarantee precision and range.

    Update: I just thought of another way: you can convert from/to a string representation of the number. Should be easy to do, but the perl side of things has to be careful not to accidentally convert it back to a number (float or int). That means you won't be able to do normal arithmatics with it (you'll have to use Math::BigInt or something similar).

      Use a 32 bit int (i.e. T_IV or T_UV) which has the advantage that any numbers in the 32 bit range can be accurately be represented,

      Note that this is not an advantage over NV (floating point). A Perl NV can exactly represent any 52-bit integer (53 if you count the sign bit) on almost any platform (I think even Crays use standard IEEE 8-byte double-precision floating point numbers). 52-bit values often are quite sufficient for such situations (address 4 peta bytes or store 142 years in microseconds).

      But if you really want to allow for full 64-bit values, my first idea was also to use a string of digits for the representation. That is probably the best choice for an XS interface, as it will conveniently and silently allow the user to switch to NV or IV if they don't need values that won't fit in such a type (or don't need full precision for some values in the case of NV).

      But doing this right will be a little tricky. In particular, you'll need to pay attention to what value types the scalar passed to you has, and which of those value type(s) is/are primary. Perhaps use the scalar's NV if SvNOK() [not SvNOKp()] or not SvPOK(), otherwise use the scalar's PV [if SvPOK() but not SvNOK()].

      - tye