3
function haha($lol)
{
   if($lol) { echo "plus"; }
   else { echo "minus"; }
}

haha(-1) echoes plus.

Is it because PHP uses twos complement? Google search wasn't really helpful.

4 Answers 4

12

PHP inherits a lot of its design decisions like this one from Perl. Perl borrowed ideas widely, but almost certainly took this particular idea from C. C inherited it from B.

B did not have different data types like int, boolean, etc, but rather just operated on memory slots, and the interpretation of each slot depended on what instructions were used on it, so it had to use some fixed rule for converting a bit pattern to boolean, and the one it chose was all zero its false, all others true.

B was a derivative of BCPL, which had a similar type system, but diverges from BCPL's definition of truth values (which has the same definition of false, but requires true to have all bits set, I.e. -1 if interpreted as a signed 2's complement integer). BCPL leaves the result of using any other value unspecified.

It is likely that B's approach was influenced by the instruction set on the PDP 7 it was originally designed for. The PDP 7 provided instructions that would conditionally execute the next instruction if its accumulator register was zero or not zero which would execute in a single cycle. Testing for equality with any other value required multiple cycles. It also had an instruction ISZ (increment and skip if zero) which could very efficiently handle loops that count up to zero, an idiom made simple if non-zero numbers are true:

c = -8;
do { ... } while (++c);
1
  • 1
    I'd point to perl borrowing from awk in this case. And while awk may borrow from others in its syntax, perl's original ideal of replacing shell, sed, and awk scripts with a consistent scripting language this origin is more likely. Now, awk borrowed from C and so forth...
    – user40980
    Oct 25, 2015 at 15:09
4

I don't know about PHP specifically, (ew,) but in all languages that I know of which allow implicit (ew,) or explicit conversions between numbers and booleans, the following holds true:

  • zero evaluates to false
  • everything non-zero evaluates to true.

And negative numbers are non-zero.

This does not really have anything to do with two's complement.

I am not sure of the precise reason why this is so, but if you think about it, if it was not to be so, then what would you rather have it be? Positive numbers vs. non-positive numbers? That would require treating -1 the same as 0, (since 0 would of course still have to mean false,) and this is asymmetric; it feels blasphemous; wicked.

I suppose there are other reasons that have to do with the simplicity which is inherent in symmetry. For example, if you compute the difference between two numbers A and B, this will be a negative number if A < B, zero if A == B, and a positive number if A > B. But if you view the difference as a boolean, then automatically you have the value of the expression A != B, irrespective of > or <. That's kind of a useful thing to have.

9
  • Thanks, but why do they evaluate to true? I thought maybe because PHP interpreter sees 255 instead of -1, but if this has nothing to do with twos complement then is it by design.
    – Vegan Sv
    Oct 24, 2015 at 22:27
  • @VeganSv I amended my answer.
    – Mike Nakis
    Oct 24, 2015 at 22:43
  • Ok, you're not sure, and you suspect is by design. I clearly remember in school I was using some language and it would evaluate positive numbers to true and negative to false and I thought it was PHP, but I was wrong.
    – Vegan Sv
    Oct 24, 2015 at 22:54
  • 3
    There are generally three schools of thought: 1) Booleans are Booleans, everything else is not a Boolean, and cannot be converted to one (e.g. Smalltalk), 2) false and nil are falsey, everything else is truthy (e.g. Ruby, many Lisps), 3) everything "empty" is falsey (0, 0.0, the empty string, the empty array, the empty list, the empty dictionary, the empty object, and of course false and nil), everything else is truthy. In PHP, the string '0' is also falsey. And then, there are languages where the strings "N", "No", "F", "False" are also falsey Oct 24, 2015 at 23:28
  • Also in many cases, a bool is stored as a byte, and the built-in constant for false is 0, and true is -1 because a bitwise NOT of 0 is -1. Oct 25, 2015 at 0:57
0

When I first read this question something about it bothered me, but I couldn't put my finger on it.

This morning I realized that what bothered me was that some people may be doing this, converting numbers to booleans. Perhaps the OP was just doing it as an academic exercise, but IMHO it should never be done in practice.

This admonition from MSDN sums it up nicely, "...You should never write code that relies on equivalent numeric values for True and False. Whenever possible, you should restrict usage of Boolean variables to the logical values for which they are designed."

-2

Google search wasn't really helpful.

This did not take long to find. From http://php.net/manual/en/language.types.boolean.php :

When converting to boolean, the following values are considered FALSE:

  • the boolean FALSE itself
  • the integer 0 (zero)
  • the float 0.0 (zero)
  • the empty string, and the string "0"
  • an array with zero elements
  • an object with zero member variables (PHP 4 only)
  • the special type NULL (including unset variables)
  • SimpleXML objects created from empty tags

Every other value is considered TRUE (including any resource).

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

1
  • 4
    The question wasn't for a list of those values, but an explanation for the design-decision leading to it. Oct 25, 2015 at 6:05

Not the answer you're looking for? Browse other questions tagged or ask your own question.