3.17 Booleans and numbers

You might have expected we had discussed this subject much earlier. But we haven't and for one very good reason. We've told you a few chapters ago that 'IF' branches if the top of the stack is non-zero. Any number will do. So you would expect that this program will print "I'm here":

     1 2 and
     if
           ." I'm here"
     then

In fact, it doesn't! Why? Well, 'AND' is a BINARY operator, not a LOGICAL operator. That means it reacts on bit-patterns. Given two numbers, it will evaluate bits at the same position.

The number "1" is "01" in binary. The number "2" is "10" in binary. 'AND' will evaluate the first bit (binary digit, now you know where that came from!). The first bit is the rightmost bit, so "0" for the number "2" and "1" for the number "1".

'AND' works on a simple rule, if both bits are "1" the result will be "1" on that position. Otherwise it will be "0". So "1" and "0" are "0". The evaluation of the second bit has the same result: "0". We're stuck with a number that is "0". False. So 'IF' concludes that the expression is not true:

     2 base ! [binary]          \ set radix to binary
     10                         ( binary number "2")
     01 AND                     ( binary number "1")
     . cr                       ( binary result after AND)

It wil print "0". However, "3" and "2" would work just fine:

     2 base ! [binary]          \ set radix to binary
     10                         ( binary number "2")
     11 AND                     ( binary number "3")
     . cr                       ( binary result after AND)

It will print "10". The same applies to other binary operators as 'OR' and 'INVERT'. 'OR' works just like 'AND' but works the other way around. If both bits are "0" the result will be "0" on that position. Otherwise it will be "1":

     2 base ! [binary]          \ set radix to binary
     10                         ( binary number "2")
     01 OR                      ( binary number "1")
     . cr                       ( binary result after OR)

It will print "11". We do not encourage the use of 'INVERT' for logical operations. You should use '0=' instead.

'0=' takes the top of the stack and leave a true-flag if it is zero. Otherwise it will leave a false-flag. That means that if a condition is true (non-zero), it will leave a false-flag. Which is exactly what a logical NOT should do.

Take a look at his brother '0<>'. '0<>' takes the top of the stack and leaves a true-flag if it is non-zero. Otherwise it will leave a false- flag.

The funny thing is 'AND' and 'OR' work perfectly with flags and behave as expected. '0<>' will convert a value to a flag for you. So this works:

     1 0<>
     2 0<>
     and if
           ." I'm here" cr
     then

Of course, you don't have to use '0<>' when a word returns a flag. You should check the glossary for details on that.