Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

String to Hex

by augustpete (Initiate)
on May 22, 2007 at 20:52 UTC ( [id://616866]=perlquestion: print w/replies, xml ) Need Help??

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

I am attempting to convert a String Decimal value to Hex, and all I get back are a series of fffff I am using printf ("%x\n",$esn) $esn declared as my $esn and the value is a character string from the Sql select statement. printng $esn before the conversion - the number's are 24600988483 Comes our as FFFFFFFF

Replies are listed 'Best First'.
Re: String to Hex
by jettero (Monsignor) on May 22, 2007 at 21:03 UTC
    You could try Math::BigInt->new('24600988483')->as_hex() ... It looks to me like your big integer is overflowing the '%x'. I wasn't aware it overflowed that smallishly.

    -Paul

Re: String to Hex
by shmem (Chancellor) on May 22, 2007 at 21:05 UTC
    You are probably on a 32bit platform. The "%x" template handles up to 2**32-1 (which is 0xffffffff), and 24600988483 is far above that value.

    update: jettero got it:

    perl -MMath::BigInt -le 'print Math::BigInt->new(24600988483)->as_hex( +)' 0x5ba554b43

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: String to Hex
by GrandFather (Saint) on May 22, 2007 at 21:08 UTC

    The problem is that the number is too big to be represented as a 32 bit integer and your Perl has been compiled to use 32 bit integers.

    For positive integers you can use:

    use strict; use warnings; use bigint; my $num = 24600988483; my @parts; while ($num) { unshift @parts, $num & 0xFFFFFFFF; $num /= 0x100000000; } printf "%x", $_ for @parts;

    Prints:

    5ba554b43

    Update: jettero's solution is much cleaner!

    Update: Unstruck on advice ;)


    DWIM is Perl's answer to Gödel
      But yours is nice too, and clean also. You mustn't be ashamed and strike through :-)

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Update: Unstruck on advice ;)

      I also agree that it deserved being unstruck. But:

      • I would $num >>= 32;
      • AIUI from earlier posts by knowledgeable people, the technique is valid for numbers such that the loop will always involve one or at most two iterations of the loop.

      Update: s/16/32/ applied above, thanks GF.

        I would $num >>= 16;

        Both methods have problems on 32-bit systems.

        GrandFather's produces the correct result and warnings, but yours gives the wrong result?

        print 24600988483 / 2**32;; 5.72786398301832 print 24600988483 / 0x100000000;; Integer overflow in hexadecimal number at (eval 24) line 1 Hexadecimal number > 0xffffffff non-portable at (eval 24) line 1 5.72786398301832 print 24600988483 >> 16;; 65535

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: String to Hex
by graff (Chancellor) on May 22, 2007 at 21:07 UTC
    Well, the problem is that each "F" in the hex representation represents 4 bits, and you can only express a value that fits within 32 bits (8 * 4) using the  printf( "%x", ... ) approach. (I even tried using  "%lx" just now, and got the same result -- just 32 bits.)

    I guess you'll need to have your perl interpreter compiled to handle 64-bit ints, or maybe use Math::BigInt, or else roll your own logic for handling values from the database that don't fit into 32 bits.

Re: String to Hex
by BrowserUk (Patriarch) on May 22, 2007 at 21:19 UTC

    For numbers upto 2**53 (~16 decimal digits), you could use this:

    sub hexFromI53{ my $n = shift; my $lo = $n % ( 2**32 ); my $hi = int( $n / 2**32 ); return sprintf "%x%08x", $hi, $lo; };; print hexFromI53( 24600988483 );; 5ba554b43 print hexFromI53( 9_007_199_254_740_992 );; 20000000000000

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://616866]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-23 19:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found