Numbers, Strings and Other Things

30 10 2010

At one of my latest interviews recently, the interviewers posed the following technical question:

Given the following statement:

echo (“012” == 012)? true : false;

What will be displayed after PHP parses it?

a. TRUE

b. FALSE

c. nothing

d. 1

e. 0

This is a very good question because it tests your understanding of PHP’s automatic conversion of strings to numbers, your comprehension of octal values, as well as your understanding of the built-in echo and what  TRUE and FALSE values are in PHP.  So, let’s use this question as a stepping stone into today’s discussion .

I could tell you the correct answer, but I’d suggest that if you have yet to figure it out that you run the code and see what result you get.  Learning from experience is a whole lot more memorable and fun than rote learning.  However, if you’re really impatient for the answer, here it is:

Answer:

But you may exclaim that I’ve shown you nothing and that is because c) nothing is the correct answer.  Let’s analyze what is going on.

First, we have a ternary condition where if the result is true, we should see something.  But if the result is false, then the built-in echo which outputs strings, will output precisely an empty string since PHP will convert the false value into an empty or null string.  But why does PHP evaluate the condition as false?

What we are looking at it would appear is an octal value embedded in a string “012” and another octval value of 012.  So, why does this comparison evaluate as an inequality?  The value on the right side of the equality symbol is undoubtedly a bona fide octal whose value is ten (or 10 in decimal terms).  But the embedded octal in the string to the left will never be recognized as such unless someone takes it upon him or herself to redo the way PHP does its parsing.

The online manual suggests that if you want to understand how PHP pulls a number out of a string that you read the UNIX manual page for strtod(3) which  is a fascinating read.  Basically PHP can parse a string with embedded decimal or even hex numbers and figure out their values but not so with octals.  Why?  Probably it has to do with one wishing to retain the validity of numeric decimal numbers that have leading zeros, such as dates.

So, PHP looks at the numeric string of “012” and translates that as having a value of twelve with a leading zero that it ignores.  Since twelve is greater than the octal value to the right of 012, i.e. ten), the condition is false.

But surely there must be some way to force PHP to recognize “012” as an octal.  Well you can feed that string as a parameter to octdec(), as follows:


echo octdec("012");

Octdec() expects that the parameter you pass in will be a valid octal number embedded in a string and then promptly
goes about translating it into its decimal representation as a value.

As far how this automatic converting works with Hex strings, here are some examples:

echo '"0xFF" == 255 ';

This condition will evaluate to true so you should see a “1” appear on your screen as a result of true being a boolean value  in PHP.

And, you can do some addition if you’d like, too, as follows:


echo ("0xFF" + 2) . '
';

Note: Since 2 is 2 whether in hex or decimal, it really doesn’t matter here that I’m adding a decimal ‘2’ to a hex value.

PHP parses the hex string and pulls out a value of 255 which it adds to 2 and the result is 257.  Incidentally, if I had added 0x2 instead the result would also depict the value of two-hundred fifty-seven in decimal terms.

If you’re feeling a little nervous about automatic conversion, you can also use a function called base_convert() which takes as parameters a numerical string and needs to know from which base do you wish to convert and into which base should the final result be.

So, we could do the following:


$strNum = "012";$frombase = 8;$tobase = 10;

echo base_convert($strNum ,$frombase , $tobase);

There’s also another way you can extract the value of an octal with PHP.

echo intval('12', 8);

The above code says that the string should be evaluated as an octal and will result in a value of ten in decimal
being displayed. If you wish you can also preface the string with the usual ‘0’ and that will also give you the correct
result.

I cam across a weird piece of code while putting this post together today.  Someone commented in the online manual with the following interesting snippet:

</pre>
$x1 = '111111111111111111';

$x2 = '111111111111111112';
echo ($x1 == $x2) ? "true\n" : "false\n";

When you run that snippet, you may be surprised by the result.

The snippet author suggests that the only way to get a valid result is to use the identity === operator.  Yes, that will work, but since we are comparing strings, I recommend instead using strcmp(), as follows:

echo strcmp($x1,$x2);

strcmp() is safe for binary data and what are strings after all?  One char or byte after another.  By evaluating each byte we can rest assured that the result will be valid.

This work is licensed under a Creative Commons License
.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: