PHP Pop Quiz Answers

Okay, pencils down.  Here are the answers and explanations to the expressions given in the PHP Pop Quiz.

php > var_dump(false/false);
PHP Warning: Division by zero in php shell code on line 1

This gives the same result and warning as division by zero, and so it makes sense that false is being interpreted as the integer 0 in the context of arithmetic operations.

php > var_dump(false/true);

This makes sense if true is interpreted as 1 in the context of arithmetic operations. This all fits with some common interpretations of Boolean algebra where 1 and 0 map to true and false, respectively. By the way, this means you can do things in PHP like:

php > var_dump(false+1);
php > var_dump(true+1);

Now for the fun ones…

php > var_dump(true+false<false^true);

At this point you’ve probably established for yourself that true is 1 and false is 0. You probably also know that ^ is the bitwise or operator. My first guess would then be that this returns bool(false) since 1+0 == 1 and 1^0 == 1, and so 1<1 is false… except that is wrong. The trick here turns out to be order of operations. In PHP the operator precedence, from highest to lowest is: + then < then ^. So, making the evaluation order explicit gives:

(((true + false) < false) ^ true)
== (((1 + 0) < 0) ^ 1)
== ((1 < 0) ^ 1)
== (false ^ 1)
== (0 ^ 1)
== 1
php > var_dump(pow(false, -true));

The pow(a, b) function takes a and raises it to the power b. If the result can be represented as an integer, then it will return an integer. Otherwise it will return a float. Algebraically, a-1 = 1/a. For example, 2-1 = 1/2. So, the interpretation of this expression is to raise false (0) to the power negative true (-1), i.e. 0-1. But, this is just 1/0, and it seems we have sneakily divided by zero again here. Why is the result different from the first expression we tried? It turns out, this is actually perfectly defined behavior for floating point numbers, and Infinity is the correct result. IEEE-754, the standard that defines floating point numbers and arithmetic, actually defines some special values to be used in overflow conditions and edge cases like this. The standard defines two zeros, positive zero and negative zero. The standard also defines some extra values, positive infinity (+Inf), negative infinity (-Inf) and not-a-number (NaN). The standard says what should happen when you divide by +0 or -0. In the case of a/+0, the result is +Inf if a is positive, or -Inf if a is negative. In the case of a/-0, the result is -Inf if a is positive, or -Inf is a is negative. If a is either +0 or -0, the result is NaN.  The latest version of the standard gives suggested values of the pow() function, for cases like this. Also of interest is that PHP doesn’t bother to compute this result itself. Unless you provide pow() with integer arguments, where the exponent is non-negative, then PHP will delegate the evaluation to the underlying C library that was used to compile PHP. Only in cases of integer arguments, where the exponent is non-negative, will PHP attempt to calculate the result itself.

php > var_dump(pow(false, false));

So, this is pretty straight forward, right? It is just zero raised to the zero power… but wait, what is that exactly? Mathematically, this expression is somewhat ambiguous. Mathematicians do not all agree on what 00 should equal in all cases. Intuition usually leads to the guess that 00 is either 0 or 1. When I showed this to another developer, I asked him what he thought it was, but before I demonstrated the actual value I had prepared an argument to make him change his mind. If he said he thinks the result will be 1, I would ask him what zero squared is, or zero cubed, or zero to the fourth. Each of these is zero, so why would zero to the zero be anything but zero? If he said he thinks the result will be 0, I would ask him what one to the zero is, or two to the zero is, or three to the zero is. Each of these is one, so why would zero to the zero be anything but one? So, in PHP, zero to the zero is one. End of story. They even mention it in an example on the documentation page for pow().

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top