# Casting hex string to int

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Hello,

Is this normal?

var_dump( is_numeric( '0xFF' ) ); // true
var_dump( (int) '0xFF' ); // 0

I would expect the second line to yield 255, since the first line
indicates that PHP recognizes the hex representation as a numeric value.

So how can I convert a string which is numeric and contains either a
decimal or a hexadecimal representation of a number to an int (or float
if it's too big)? I could check with a regex and use hexdec() if it's
hex and a simple cast otherwise, but this is not elegant.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

## Re: Casting hex string to int

Op 07-08-10 17:30, Thomas Mlynarczyk schreef:

\$>  php -r 'var_dump( (int) '0xFF');'
int(255)

\$> cat hexdec.php
<?php
var_dump( is_numeric( "0xFF" ) );
var_dump( (int)"0xFF" );
\$s=(int)"0xFF";
var_dump( \$s );
print hexdec("FF");
print "\n";
?>
\$> php hexdec.php
bool(true)
int(0)
int(0)
255

hmmm, indeed, strange......

--
Luuk

## Re: Casting hex string to int

Luuk schrieb:

So this works, but...

...that doesn't?

Then it's even stranger than I thought.

Meanwhile I found a solution for my problem:

intval( \$string, 0 ) seems to do just what I want: It will automatically
detect if it's hex, oct or dec and return the expected result. If the
value is out of range for int, the max or min int value will be
returned. Only trouble is: according to the docs (user comment), this
feature is undocumented. So, strictly speaking, I should not use it.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

## Re: Casting hex string to int

On 08/07/2010 12:27 PM, Thomas Mlynarczyk wrote:

It is the right solution. but, where did you read that it is undocumented?

â†’ http://php.net/intval

## Re: Casting hex string to int

Marious Barrier wrote:

In that page, the use of base '0' to automatically determine the base,
is not documented in the general blurb.

## Re: Casting hex string to int

On 08/07/2010 04:35 PM, The Natural Philosopher wrote:

Lol, I did not get he was talking about using the 0.

## Re: Casting hex string to int

Marious Barrier wrote:

Fairy Nuff :-)

Odd that they DONT, probably because there are cases where it breaks..

## Re: Casting hex string to int

The Natural Philosopher schrieb:

Well I had some issues, like one must first check the string with
is_numeric(), otherwise intval() will happily parse things like "42zzz"
as 42. But then, "42e1" is numeric as well, but intval() doesn't regard
it as a valid integer, even though 420 would be perfectly okay. Because
of that and other reasons I have finally decided to avoid intval
altogether and do it the regex way.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux Ã  avoir tort qu'ils ont raison!
(Coluche)

## Re: Casting hex string to int

Thomas Mlynarczyk wrote:

generally the reason why I used to avoid regex and write my own routines
in C :-)

Quicker to write something you DID understand, than crap about trying to
work out the convoluted brain of whoever dreamed up regexp in the first
place...

## Re: Casting hex string to int

Thomas Mlynarczyk wrote:

No, because 'e' is not a character for integers.  It is, however, valid
with floating point values.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================

## Re: Casting hex string to int

Jerry Stuckle schrieb:

Yes. But a floating point number without decimals and not greater than
PHP_INT_MAX nor smaller than -PHP_INT_MAX - 1 could, without loss of
information, be converted to an integer. 42e1 represents the same number
as 420, it's just another way of writing it. Thus, intval() ought to be
able to recognize it.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux Ã  avoir tort qu'ils ont raison!
(Coluche)

## Re: Casting hex string to int

.oO(Thomas Mlynarczyk)

I don't think so. 42E1 is a notation for floats, not for integers. Even
if there are not decimals, it is still a float value. 420 and 420.0 are
the same number, but technically they're different and most likely even
stored in different ways internally.

Micha

## Re: Casting hex string to int

That is true, however, intval() is a type-casting function.  So, while
"42e1"
is a float notation, that doesn't imply that the following should
behave any differently, yet they do:

intval("42e1");
intval("420.0");
intval(420.0);

The behavior is consistent, however.  If you pass intval a string, it
will read /^([\d]+)/ and assume base-10.  For other notations, you can
either specify a base, or specifically cast it:

intval("0xff");     // 0
intval(0xff);       // 255
intval("0xff", 16); // 255

intval("0377");     // 377
intval(0377);       // 255
intval("0377", 8);  // 255

intval("42e1");         // 42
intval(42e1);           // 420
intval((float) "42e1"); // 420

It would be handy to have a single function however that could read an
unknown-formatted string and come up with a "best guess" to an integer
value based on these other notations.  Obviously there's problems:
0800 = 800 (not valid octal), but 0700 = 448?

## Re: Casting hex string to int

matt schrieb:

[Integer values in hex, dec or oct representation]

Well, that could be solved by defining an unambiguous syntax for the
different representations. I have now come up with the following (more
general) solution which does what I want:

function parse( \$str )
{
if ( !is_string( \$str ) ) return \$str;
\$str = trim( \$str );
if ( \$str === '' or strtolower( \$str ) === 'null' ):
return null;
elseif ( preg_match( '~^("|')(\.|(?!|\).)*\$~', \$str ) ):
return stripcslashes( substr( \$str, 1, -1 ) );
elseif ( preg_match( '~^0[xX][0-9a-fA-F]+\$~', \$str ) ):
return hexdec( \$str );
elseif ( preg_match( '~^0[oOqQ]?[0-7]+\$~', \$str ) ):
return octdec( \$str );
elseif ( preg_match( '~^0[bB]?[01]+\$~', \$str ) ):
return bindec( \$str );
elseif ( is_numeric( \$str ) ):
return (int) ( \$str = (float) \$str ) == \$str ? (int) \$str : \$str;
elseif ( is_int( \$pos = stripos( 'false no off true yes on', \$str )
) ):
return \$pos > 12;
elseif ( defined( \$str ) ):
return constant( \$str );
else:
return \$str;
endif;
}

It recognizes numbers in hex, dec, oct, bin and float notation,
booleans, defined constants and quoted strings:

'255' -> (int) 255
'0xFF' -> (int) 255
'0377' -> (int) 255
'0b11111111' -> (int) 255
'2550e-1' -> (int) 255
'3.14' -> (float) 3.14
'' -> null
'null' -> null
'false' -> false
'yes' -> true
'E_ALL' -> (int) 6143
'"\x41\x42\x43"' -> (string) "ABC"

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)

## Re: Casting hex string to int

Thomas Mlynarczyk wrote:

No arguments that it is within range.  But that also has nothing to do
with the fact 'e' is not a valid integer character.  It is only valid
for floating point numbers.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================

## Re: Casting hex string to int

Isn't that an oxymoron?

## Re: Casting hex string to int

thomas@mlynarczyk-webdesign.de wrote:

No, not quite. The shell is doing funny stuff with the quotes.
Because he has single quotes inside single quotes, the shell
takes them out, so he gets this inside:   (int)0xFF
which of course is 255. See:

\$ php -r 'var_dump((int)'0xFF');'
int(255)

But change the quotes:

\$ php -r 'var_dump((int)"0xFF");'
int(0)

Gotta watch those shell quoting tricks...

## Re: Casting hex string to int

The cast to (int) calls the C function strtod, which does not understand
hexadecimal.  You don't really need a regex; you can just check for "0x" as
the first two characters.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

## Re: Casting hex string to int

Tim Roberts schrieb:

True. But I finally opted for the regex version after all. Firstly
because of some "quirks" regarding the use of intval/is_numeric and
secondly because that gives me more control over what's happening. Plus,
I can support binary representations as well.

Thanks & greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)