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

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

Is there a way to "unpack" unsigned long long ints? I can see that there isn't a letter symbol for those, but I was just wondering if there was a way to go about it that meant I could ignore messing around with endianness and stuff.

Replies are listed 'Best First'.
Re: unpacking unsigned long longs
by ambrus (Abbot) on Jul 02, 2009 at 19:32 UTC

    Just unpack a signed long long int instead and then convert it to unsigned by bitwise anding with 0xffffffffffffffff (with the right number of fs in case I goofed it up). Or try Math::Int64::native_to_uint64.

    Update: If you are on a 64-bit platform (or you are on a 32-bit platform but your perl is specifically compiled so that perl integers are 64 bit which is rare), then you can use the "J" unpack template, and, in the first case, "L!" as well. Otherwise you could also unpack two 32-bit integers and combine them in the right direction.

Re: unpacking unsigned long longs
by ikegami (Patriarch) on Jul 02, 2009 at 22:48 UTC

    I can see that there isn't a letter symbol for those,

    More like you can't see that there is a letter symbol for those. Several symbols, actually. Here's a convenient table of them:

    Byte orderUnsignedSigned
    Local System'sQq
    NetworkQ>q>
    Little-EndianQ<q<

    Of course, that only works on builds of Perl that can actually support integers that large.

      More like you can't see that there is a letter symbol for those.
      Is the condescending attitude really necessary here? If I may suggest the following alternate wording:
      You probably just missed it (which can be easy to do amongst the many letter symbols that pack uses):
      Then give your little table... (I like it when you do that in your nodes. Everything is suddenly clear and understandable. You are good at those tables.)

      See how easy that is? Do you not feel better taking a positive slant rather than starting with a deliberate insult?

      So I guess "Quad" means 4 int lengths? That makes sense, and also explains why I didn't find anything while searching through docs for "long long". Thanks!

        So I guess "Quad" means 4 int lengths?

        Both this question and your original question are very ambiguous.

        • A C int is at least 16 bits.
        • A C long is at least 32 bits.
        • A C long long is at least 64 bits.

        I can't divine what your language and compiler chooses for int and long long, so please stop asking question in terms of ints and ask them in terms of bits or bytes.

      Also: is there an easy way to tell if I have perl compiled to support numbers that large?

        The necessary info is in Config.

        $ perl -MConfig -le'print $Config{ivsize}' 4

        You can see that value in perl -V as well.

        Of course, you could just try unpack 'Q'.

        $ perl -le'unpack "Q", chr(0)x8; print "ok"' Invalid type 'Q' in unpack at -e line 1.
Re: unpacking unsigned long longs
by suaveant (Parson) on Jul 02, 2009 at 18:54 UTC
    Convert::Binary::C looks promising

                    - Ant
                    - Some of my best work - (1 2 3)

Re: unpacking unsigned long longs
by Marshall (Canon) on Jul 03, 2009 at 03:46 UTC
    Short answer: Yes! It is possible to unpack and use this in Perl!
    Other questions are what you mean by unsigned long long int? 64 bits, I guess?

    No this "endian" stuff always matters. Sorry to disappoint you. It is a "bummer" but that is the way that it is.

    In order to write the Perl code, I would have to know the order of the byte stream in the file and then how that should look in memory.

    Another way to do this if I know the input format, is to write a simple 'C' (or Perl) program for you that translates all these numbers into text as a pre-processing step. Then you just read these numbers in. For you, that avoids this "endian" stuff! The binary to text conversion has to know, but your code wouldn't. But sounds like your code would have to be able to handle 64 bit ints.