debuggable

 
Contact Us
 

False == 0, or not?

Posted on 13/8/07 by Felix Geisendörfer

So far I've always thought false would evaluate to 0 when used in a computational context. Turns out that this isn't always the case.

// The world as we know it:
echo 0 + 1; // 1
echo false + 1; // 1
echo 0  > -1; // true

// But what is that ...?
echo false  > -1; // false

Now if anybody does have an explanation for this, I'd be glad to hear it. I randomly stumbled upon this when arguing with Mariano today if setting Model::recursive to 'false' has the same effect as setting it to '-1'. Turns out that cake uses a statement like this: if ($recursive > -1) in the core which in turn makes -1 and false do exactly the same thing.

Btw., if you need to work around this behavior you can use something like this:

echo (int)false > -1; // true

More posts are to come,
-- Felix

 

You can skip to the end and add a comment.

Grant Cox  said on Aug 13, 2007:

PHP is stupid when performing comparison against different types, unless you use a strict comparison (===) it will always convert the parameters to be the same type (whichever is the simplest). In the case of (false > -1) it will convert the -1 to a boolean first, which I assume is false. And (false > false) is not true.

This is why any non-numeric string will always == 0. The string is converted to an int (which is always 0 if the string is non-numeric). So something like in_array('abc', array('foo',0,'bar')) will return true - because (0 == 'abc'). This is what the extra option for in_array is for, but who really remembers to use it until bitten?

Felix Geisendörfer said on Aug 13, 2007:

Grant Cox: Very insightful. Anybody disagreeing / backing this up with manual references? I'd think -1 would evaluate to true in a boolean context but other then that this sounds logical. The in_array thingy is particular scary however : ).

Grant Cox  said on Aug 14, 2007:

There were some bugs filed (marked as bogus) about this, but I can't find them at the moment. But http://www.php.net/manual/en/types.comparisons.php demonstrates that (true == -1), so you were really checking if (false > true).

But that you can say ("0" != "abc"), but (0 == "0") and (0 == "abc"), just seems wrong to me. I mean, I can see how it gets there, but it still seems wrong.

PHPDeveloper.org said on Aug 14, 2007:

Felix Geisendorfer's Blog: False == 0, or not?...

...

Todd Pinel  said on Aug 14, 2007:

This is from the PHP certification study guide.

A number (either integer or floating-point) converted into a Boolean becomes
false if the original value is zero, and true otherwise.

and also this

A string is converted to false only if it is empty or if it contains the single character
0. If it contains any other data—even multiple zeros—it is converted to

true.

and also this

When converted to a number or a string, a Boolean becomes 1 if it is true, and
0 otherwise.

So it looks like php is converting your -1 to a boolean which by the first statement would make it true, since only 0 evaluates to false. So the conditional becomes false > true , which by the third statement would be false.

false == 0 should be true because 0 would be converted to a boolean which by statement 1 would make it false. So false == false would be true.

Let me know if you think I misread anything, but the only thing I'm not 100% about is how php decides to convert data types. Why does it convert your -1 into a boolean to evaluate the conditional? Why not change the boolean into an integer then evaluate.

Todd Pinel  said on Aug 14, 2007:

Changing the order does not change the result either, so -1 < false still gives you false. Maybe there is some order of precedence? Haven't got to that part in the study guide yet I guess :D

[...] Felix Geisendorfer has come across something interesting in his coding - an issue where false might not be false in the right situation. So far I’ve always thought false would evaluate to 0 when used in a computational context. Turns out that this isn’t always the case. [...]

phpNoob said on Aug 14, 2007:

Jesus. echo false > -1 equates to echo false > true which is ofcourse false!

Any non-zero integer is true, and always has been.

Todd Pinel  said on Aug 14, 2007:

phpNoob how do you know false > true equates to false?

Did you know that false

Todd Pinel  said on Aug 14, 2007:

Did you know that true > false is true.

I've been programming for a while and I don't think I've ever quite come across or used a conditional in this way, I don't think it's very intuitive.

Lachlan Donald said on Aug 15, 2007:

The === operator is an equality check AND a type check. This means that false === 0 actually equals false, because whilst the values might be equal, false is of type boolean and 0 is of type integer.

As far as the non-strict comparisons go, -1 is actually true. From:

http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting

"-1 is considered TRUE, like any other non-zero (whether negative or positive) number!"

So false > -1 gets type juggled to false > true, which then gets evaluated as 0 > 1, which is of course false :)

Steven Hayter said on Sep 12, 2007:

My preferred explanation, false is ((unsigned int) 0), when you evaluate that statement, the operation takes the signedness of the first operand, ergo your doing an 'unsigned greater than' operation. -1 is 0xffffffff as a 32 bit int, which as an unsigned number is about 4 billion.

So:
echo false > -1

Is really:

echo 0 > 4294967295

Which you can understand is false... my background is C, same rules apply there too.

Citytopper said on Aug 06, 2008:

Same problem i got in my script.

In my program, array_search() returns false if element is not found in array or it will return key. Now, i am not able to differentiate 0 and false.

Can you tell me how can i do this?

$industry = 'computer';
$industryarr[0] = 'computer';

if(array_search($industry,$industryarr)==false)
{

echo "Archana";

}

else

{

}

runishe  said on Oct 07, 2008:

The oldschool trick is:

if(strlen (array_search($industry,$industryarr)) > 0) {

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.