Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

convert hex string to hex number

by zentara (Archbishop)
on Jul 02, 2008 at 21:35 UTC ( #695205=perlquestion: print w/ replies, xml ) Need Help??
zentara has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I ran into a little glitch converting a hex string to a hex number. I construct a string like 0x3cb37180, but I can't get it to be evaluated as a hex number. I tried the add 1 subtract 1 trick to change context but no go. Is there some unpack/pack method I can use on it?
#from some Gtk2 code my $hex = sprintf( "0x%02x%02x%02x40", $radj1->value, # 0..255 $gadj2->value, # 0..255 $badj3->value, # 0..255 ); print "$hex\n"; # something like 0x3cb37140 appears # and is what the fill-color-rgba wants below # but it claims it's not numeric $hex += 0x1; $hex -= 0x1; my $resp= ($hex) ? "$hex is numeric\n" : "$hex is not numeric\n"; print $resp; $rect->set('fill-color-rgba' => $hex ); # claims $hex is not numeric

I'm not really a human, but I play one on earth CandyGram for Mongo

Comment on convert hex string to hex number
Download Code
Re: convert hex string to hex number
by pc88mxer (Vicar) on Jul 02, 2008 at 21:41 UTC
    Use the hex() function to convert the string it to an integer. It even conveniently ignores the 0x prefix.

      Or since you know your string starts with 0x, you can eval it.

      my $hex = '0x3cb37140'; my $num = eval $hex; # 1018392896
Re: convert hex string to hex number
by FunkyMonk (Canon) on Jul 02, 2008 at 21:50 UTC
    Disclaimer: I know nothing about any perl Gtk modules!

    There isn't such a thing as a "hex number" in Perl. There are strings that are used to represent hex numbers and they can be converted to integers using oct or hex.

    Is the following code any help?

    my $hex = "0x3cb37180"; my $dec = oct $hex; say $dec; # 1018392960 say sprintf "0x%X", $dec; # 0x3CB37180

    Since you didn't say which module you're using I couldn't check it's documentation to check what $rect->set is expecting

    Unless I state otherwise, all my code runs with strict and warnings
      There isn't such a thing as a "hex number" in Perl.

      Then how do you explain this ...

      perl -le "print 0x10 + 1" 17

        With perldata. Search for "Scalar value constructors". Your 0x10 is a numeric literal.


        _($_=" "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}
      hex(0xAC530000) result Integer Overflow
Re: convert hex string to hex number
by waldner (Beadle) on Jul 02, 2008 at 21:53 UTC
    my $hex="0x3cb37140"; my $num=oct($hex); print "$num\n";
Re: convert hex string to hex number
by shmem (Canon) on Jul 02, 2008 at 22:25 UTC

    The function sprintf returns a string, and "0x3cb37140" is a string, while the bareword (in code) 0x3cb37140 is not - it is converted to a number. You can convert the string to a number with hex or eval. Also, adding and subtracting 0x1 doesn't give the result you expected:

    use Devel::Peek; my $hex = sprintf( "0x%02x%02x%02x40", 60,179,113 ); print "\n\$hex as returned from sprintf:\n"; Dump($hex); my $num = hex $hex; print "\$hex hex()ed:\n"; Dump($num); $hex += 0x1; print "\$hex augmented with 0x01:\n"; print $hex,"\n"; __END__ $hex as returned from sprintf: SV = PV(0x8c90c20) at 0x8c90750 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x8cb34f0 "0x3cb37140"\0 CUR = 10 LEN = 12 $hex hex()ed: SV = IV(0x8cabcac) at 0x8c9078c REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 1018392896 $hex augmented with 0x01: 1

    Strings are stored in a PV (pointer value) slot of a SV (scalar value), while integers get stored in the IV (integer value) slot of an SV. A variable can even carry both representations:

    my $hex = sprintf("0x%02x%02x%02x40", 60,179,113); $hex = hex($hex); Dump($hex) __END__ SV = PVIV(0x84d3b10) at 0x84d1cdc REFCNT = 1 FLAGS = (PADBUSY,PADMY,IOK,pIOK) IV = 1018392896 PV = 0x84e5608 "0x3cb37140"\0 CUR = 10 LEN = 12


    _($_=" "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: convert hex string to hex number
by zentara (Archbishop) on Jul 03, 2008 at 12:48 UTC
    Thanks everyone for all the insights. As it turned out, just converting it to oct, as waldner suggested, worked the easiest. Other solutions seemed to lop off leading 0's or for whatever reason would not be accepted by Gtk2 as hex. If I hard code a number with a leading 0x it would accept it, but it wouldn't accept any 0x in a variable.... it had to be converted to a oct or decimal number.
    #!/usr/bin/perl my $x = 0; my $y = 0; my $z = 255; my $hex = sprintf( "0x%02x%02x%02x40",$x,$y,$z); print "$hex\n"; #works print "hex $hex\n"; my $oct = oct $hex; print "oct $oct\n"; # $rect->set('fill-color-rgba' => $oct ); # works as hex, but leading 0x not acceptable to Gtk2 my $hex1 = sprintf "0x%08x", $oct; print "hex1 $hex1\n"; #$rect->set('fill-color-rgba' => $hex1 ); # pukes on the 0x # would work if I eval'd $hex1, which converted it to decimal

    I'm not really a human, but I play one on earth CandyGram for Mongo

      The oct function doesn't "convert" a number to octal. It parses a string which contains the octal representation of a number (and in fact also quietly supports binary and hexadecimal notations too) and returns it as an integer. It essentially acts like eval, but supports an incredibly tiny subset of Perl.

      $number = oct('0644'); $number = eval('0644'); # same

      In your particular case, you could just do this:

      my $n = ($x<<24) + ($y<<16) + ($z<<8) + 0x40; $rect->set('fill-color-rgba' => $n);

      Which will probably run quite a lot faster as it's pretty basic integer maths - just bit shifting and addition.

      An alternative (no faster nor slower) than the above is:

      my $n = ($x<<030) + ($y<<020) + ($z<<010) + 0x40; $rect->set('fill-color-rgba' => $n);

      Why would you want to do it that way? Because if you're familiar with octal it might help you see what's going on a little better.

      Or you can use multiplication instead of bit shifting. This might be a little slower, but if you're unfamiliar with bitwise operations, might be a little clearer:

      my $n = ($x * 2**24) + ($y * 2**16) + ($z * 2**8) + 0x40; $rect->set('fill-color-rgba' => $n);

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://695205]
Approved by pc88mxer
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2014-10-31 22:50 GMT
Find Nodes?
    Voting Booth?

    For retirement, I am banking on:

    Results (225 votes), past polls