Forth DISCUSSION

Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

Started by mark Forth logical ANDwell-formed flagsbitwise operatorsINVERT versus 0=true flag
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

mark Forth Forum
#1

I test two conditions before starting a motor: a speed value must be non-zero and a status register must have bit 1 set. My word does SPEED @ STATUS @ 2 AND AND IF START THEN. With speed 1 and status 2 the motor does not start, although both values are "true". With speed 3 it does start.

Is there a separate logical AND in Forth? How are flags supposed to be combined, and what is the correct replacement for the NOT I see in old listings?

Community replies 5

Re: Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

#2

Forth has only the bitwise AND, OR and XOR. They work as logical operators only when both operands are well-formed flags, meaning exactly 0 or -1 (all bits set). Your operands are raw numbers: 1 is binary 01 and the masked status is binary 10. They share no bits, so 1 2 AND is 0.

With speed 3, binary 11, bit 1 happens to overlap and the result is 2, which IF accepts as true. The code is testing bit overlap, not truth.

Re: Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

#3

Convert each condition to a proper flag before combining. 0<> turns any non-zero value into -1 and leaves 0 as 0; on a minimal system without it, 0= 0= does the same. The test becomes SPEED @ 0<> STATUS @ 2 AND 0<> AND IF START THEN. With speed 1 and status 2 that is -1 -1 AND, which is -1.

Comparison words such as =, <, 0= and U< already return well-formed flags, so X @ 0> Y @ 100 < AND needs no extra step.

Re: Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

#4

This is the reason standard Forth defines true as all bits set rather than 1. With 0 and -1, the bitwise words double as logical ones: AND and OR behave as expected, and INVERT, which flips every bit, turns -1 into 0 and 0 into -1. With a true value of 1, inverting would give -2, which is still non-zero.

A well-formed flag is also a usable mask: flag 100 AND yields 100 when the flag is true and 0 when it is false, which lets you write selections without a branch.

Re: Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

#5

On NOT: earlier standards disagreed about it. In some it was the logical test for zero, in others the bitwise complement, so the ANS standard left the name out and provides two unambiguous words. Use 0= to negate a truth value; it works on any number and always returns a well-formed flag. Use INVERT for a bitwise complement, and as a logical not only on values you know are 0 or -1.

When porting an old listing, find out which meaning its NOT had: 5 0= is 0, but 5 INVERT is -6, which IF treats as true.

Re: Forth AND, OR and INVERT are bitwise: how do I combine two conditions correctly?

#6

Note also that AND never short-circuits: both operands are already on the stack before it runs. If the second condition is only safe when the first holds, for example fetching through a pointer that may be zero, nest the tests instead: PTR @ ?DUP IF @ 0<> IF START THEN THEN.

For a run of independent conditions, a common style is to factor them into a word that returns one flag, such as : READY? ( -- flag ) SPEED @ 0<> STATUS @ 2 AND 0<> AND ;, so that the caller reads READY? IF START THEN.

TEP COMMUNITY