Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Unpack 64 bit value

by nagalenoj (Friar)
on Sep 10, 2009 at 08:17 UTC ( #794508=perlquestion: print w/replies, xml ) Need Help??
nagalenoj has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

How can I unpack a 64 bit value? I've reffered the perlpacktut and used 'q'. But it's reporting the error as follows,

Invalid type 'q' in pack at line 196.

Replies are listed 'Best First'.
Re: Unpack 64 bit value
by Utilitarian (Vicar) on Sep 10, 2009 at 08:45 UTC
    q and Q require that your system support 64 bit ints.
    You may have to work around this limitation if you are on a 32 bit platform. tye produced an interesting 64-bit unpack here
Re: Unpack 64 bit value
by almut (Canon) on Sep 10, 2009 at 08:37 UTC

    From perldoc -f pack:

    q A signed quad (64-bit) value. Q An unsigned quad value. (Quads are available only if your system supports 64-bit integer values _and_ if Perl has been compiled to support thos +e. Causes a fatal error otherwise.)
Re: Unpack 64 bit value
by salva (Abbot) on Sep 10, 2009 at 11:17 UTC

      Looking at the source, it looks like a very efficient implementation. It does native 64-bit arithmetic through overloaded operators. It doesn't use Math::BigInt or the like. (The number is stored in the NV slot of a blessed SV.)

      ...but native 64-bit arithmetic isn't supported by my compiler or it isn't enabled. Does any 32-bit compiler on a 32-bit platform have support for 64-bit arithmetic?

      It would be nice if it downgraded to using Math::BigInt if necessary.

        ...but native 64-bit arithmetic isn't supported by my compiler or it isn't enabled. Does any 32-bit compiler on a 32-bit platform have support for 64-bit arithmetic?

        I believe that C99 specifies support for the long long int (64 bits or bigger) type as mandatory, so any modern compiler aiming to be C99 compliant should have 64 bits support.

        My initial plan was to add a fallback mode able to handle 64 bit arithmetic with 32 bit ints (it shouldn't be too difficult) but until today nobody had asked for it so it just remained undone...

        Can you give me the details of your system, OS, compiler, etc? are you sure it doesn't support 64 bit integers in any way?

Re: Unpack 64 bit value
by Marshall (Abbot) on Sep 10, 2009 at 08:41 UTC
    Update: this post is obviously not clear...I am not familiar with 64 bit ASM, so I will defer to folks who claim that knowledge.

    Update: I guess I am having a "bad hair day"...Obviously this post is not clear. Sorry about that. The general idea is correct. In the Intel bit world, reading bytes 1,2,3,4 (for 32 bit integer) from a disk file means byte order 3,4,1,2 in memory. I know that's goofy and I have no defense! This is "unpack" with V4 format. I think Motorola is something like N4 format (1,2,3,4). If you understand this part, everything below may make sense.

    This (Unpack) will be platform specific. There is a difference between what is called "little Endian" and "big Endian". Here is a wiki article on this: The basic thing is whether most significant byte or word appears first or second in the sequence.

    It is absolutely crucial that you understand binary representations and how to convert a linear set of bytes in a file to "endianness" for your machine.

    Update: If 32 bit (4 byte order) doesn't matter then certainly 64 bit (8 byte order) won't either. If so, skip the rest of this post. If you are going to process an array in binary format in 'C' or other languages, or dump a Perl binary structure, this post is direct to the point.

    Normally 32 bits is enough for a 64 bit integer value conversion because the most significant 4 bytes are all zero's (positive number) or all one's (negative number, sign bit extension). A Perl float can handle something like 53 bits.

    There is likely to be "big" problems if you have an int that cannot be represented in 32 bits. That would mean that you can't easily pass this value as a simple int to other Perl subs, etc.

    So basically if upper 32 bits are all zero's or all one's, it doesn't matter. If that is not true, then you have "big int" problems.

    I guess we get into the case of an "unsigned" 32 bit int where the most significant bit is 1. In that case the upper 32 bits would also be zero and this is a specific case of something that can't be represented as 32 signed bits.

      This is just *so* wrong. Endianness is irrelevant to whether q is a valid format.
        I don't have access to a 64 bit platform.. "Endianness" is always relevant as there is fundamental difference between say how Intel and say Motorola machines work.

        This goes to the hardware level about how data is actually stored in sequential memory locations and is enforced by the hardware. If I do a binary byte dump to disk, of say array of 32 bit values on a VAX or Intel platform, nothing is gonna change the fact that this same array will look different on the disk from a binary byte dump from a Motorola platform.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://794508]
Approved by planetscape
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2018-02-22 21:18 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (299 votes). Check out past polls.