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

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

I tried to convert the string "0x000fffff7f00fffc" with 32-bit perl-5.8.8 and 64-bit perl-5.8.5 with the hex() function. Both say: Hexadecimal number > 0xffffffff non-portable How do I get 64-bit hexidecimal from string? Thanks.

Replies are listed 'Best First'.
Re: Is there a 64-bit hex()?
by almut (Canon) on Feb 10, 2009 at 09:52 UTC

    You could also use Math::BigInt:

    #!/usr/bin/perl use Math::BigInt; my $hex = "0x000fffff7f00fffc"; my $dec = Math::BigInt->new($hex); print "$hex = $dec\n"; # also works with even larger numbers... $hex = "0x000fffff7f00fffc000fffff7f00fffc000fffff7f00fffc000fffff7f00 +fffc"; $dec = Math::BigInt->new($hex); print "$hex = $dec\n"; __END__ 0x000fffff7f00fffc = 4503597463175164 0x000fffff7f00fffc000fffff7f00fffc000fffff7f00fffc000fffff7f00fffc = 2 +826953945157987506191153074870519081847080605839924685569054791495483 +3916

    Update: maybe it's worth noting that $dec is treated as a number internally (as opposed to a simple string representation of it), i.e. you can calculate with it. The respective operators are overloaded.

Re: Is there a 64-bit hex()?
by JavaFan (Canon) on Feb 10, 2009 at 08:01 UTC
    Just because perl issues a warning, it doesn't mean perl doesn't do the right thing. It's true, converting "0x000fffff7f00fffc" with hex is non-portable as it won't do the same thing on a 32-bit perl (to which I say, so what? Adding number isn't portable either, as you may get different results as well, but addition doesn't come with a warning).
    $ perl -wE 'say hex "0x000fffff7f00fffc"' Hexadecimal number > 0xffffffff non-portable at -e line 1. 4503597463175164
    Just use your 64-bit perl, and turn off the warning.
    perl -E 'say hex "0x000fffff7f00fffc"' 4503597463175164
      Better yet:
      no warnings 'portable'; # Support for 64-bit ints required
      I just want to clarify my understanding here.

      So perl is providing the decimal equivalent of the 64 bit hex string given to it by saying that this hex string is equivalent to the following decimal number: 4,503,597,463,175,164.

      The remaining question is about portability, or more specifically, will you get the same value regardless on which machine you run this perl code (ie would some other run produce a different decimal representation (assuming all would agree to interpret a 64 bit hex number as a 64-bit unsigned integer representation without any Endian manipulation needed, that is just straight binary from MSbit to LSbit from left to right) )?

      And/Or would one even get an answer on some other machine (would some Perl interpreter, running on some hardware, not provide any result) ?

        If you get a different result on a different platform, assuming both perls are compiled with 64-bit integers you have discovered a currently unknown bug.

        But you are likely to get a different result if you do the same with 32-bit integer perl.

        The portability issue the warning warns about is the portability between 32-bit and 64-bit perls. (perls, not hardware).

Re: Is there a 64-bit hex()?
by moritz (Cardinal) on Feb 10, 2009 at 07:55 UTC
    When in doubt, try pack or unpack. perlpacktut is a nice introduction.

    You can convert it to a binary string, but not to a portably to an integer, because it simply doesn't fit into the CPU registers.

      But the return value of hex() usually isn't an integer in the CPU-register sense!

      And even when it is, plenty of languages can handle 64-bit integers on 32-bit hardware. There's no law that states that all variables must fit into a single CPU register. (How would strings ever work if that were the case?)

      This kind of thing can be done portably. Therefore, it is legitimate to be puzzled about why Perl complains about it.

        But the return value of hex() usually isn't an integer in the CPU-register sense!

        Right, it's an IV, which points to a native integer.

        And even when it is, plenty of languages can handle 64-bit integers on 32-bit hardware.

        With the appropriate amount of emulation, yes.

        Note that perl is written in C, and I don't think that C makes any guarantees for the availability of a 64 bit integer type. Many other language implementations "solve" this problem by ignoring platforms or compilers that don't do what they want, but perl's focus is usually stronger on portability.

        There's no law that states that all variables must fit into a single CPU register. (How would strings ever work if that were the case?)

        Sure there's no such law, but if they don't, they are generally not as efficient.

      I need a hex value.
        You have a hex value. What do you want to do with it?

        Or asked differently - if string of the form 0x00ff... isn't a hex value for you, what is a hex value in your opinion?

Re: Is there a 64-bit hex()?
by ELISHEVA (Prior) on Feb 11, 2009 at 07:48 UTC
    The Math::Fleximal module lets you do math using any numeric base, any "digit" set, and no upper limit on the size of numbers.

    Best, beth