Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

String to Hex

by augustpete (Initiate)
on May 22, 2007 at 20:52 UTC ( #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

Comment on String to Hex
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 (Canon) 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 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 GrandFather (Cardinal) 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 BrowserUk (Pope) 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
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? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2014-09-17 18:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (94 votes), past polls