There's more than one way to do things PerlMonks

### convert hex string to hex number

by zentara (Archbishop)
 on Jul 02, 2008 at 21:35 UTC 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",
);

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

Replies are listed 'Best First'.
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 shmem (Chancellor) 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
PV = 0x8cb34f0 "0x3cb37140"\0
CUR = 10
LEN = 12
\$hex hex()ed:
SV = IV(0x8cabcac) at 0x8c9078c
REFCNT = 1
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
IV = 1018392896
PV = 0x84e5608 "0x3cb37140"\0
CUR = 10
LEN = 12

--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: 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 FunkyMonk (Chancellor) 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.

--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}```
hex(0xAC530000) result Integer Overflow
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);

Create A New User
Node Status?
node history
Node Type: perlquestion [id://695205]
Approved by pc88mxer
help
Chatterbox?
 [LanX]: suitable what? ... insult? [Discipulus]: goodby stress.. LanX you always reminded me of Sean Connery. .. shmem .oO( someday I'll do something... and then I'll make it big. Now is the time! ) [LanX]: don't forget to flush the water [shmem]: the day will come when LanX hits the fan

How do I use this? | Other CB clients
Other Users?