Next: , Previous: , Up: Forth Tutorial   [Contents][Index]

### 3.17 Flags and Comparisons

In a false-flag all bits are clear (0 when interpreted as integer). In a canonical true-flag all bits are set (-1 as a twos-complement signed integer); in many contexts (e.g., `if`) any non-zero value is treated as true flag.

```false .
true .
true hex u. decimal
```

Comparison words produce canonical flags:

```1 1 = .
1 0= .
0 1 < .
0 0 < .
-1 1 u< . \ type error, u< interprets -1 as large unsigned number
-1 1 < .
```

Gforth supports all combinations of the prefixes `0 u d d0 du f f0` (or none) and the comparisons `= <> < > <= >=`. Only a part of these combinations are standard (for details see the standard, Numeric comparison, Floating Point or Word Index).

You can use `and or xor invert` as operations on canonical flags. Actually they are bitwise operations:

```1 2 and .
1 2 or .
1 3 xor .
1 invert .
```

You can convert a zero/non-zero flag into a canonical flag with `0<>` (and complement it on the way with `0=`; indeed, it is more common to use `0=` instead of `invert` for canonical flags).

```1 0= .
1 0<> .
```

While you can use `if` without `0<>` to test for zero/non-zero, you sometimes need to use `0<>` when combining zero/non-zero values with `and or xor` because of their bitwise nature. The simplest, least error-prone, and probably clearest way is to use `0<>` in all these cases, but in some cases you can use fewer `0<>`s. Here are some stack effects, where fc represents a canonical flag, and fz represents zero/non-zero (every fc also works as fz):

```or  ( fz1 fz2 -- fz3 )
and ( fz1 fc  -- fz2 )
and ( fc  fz1 -- fz2 )
```

So, if you see code like this:

```( n1 n2 ) 0<> and if
```

This tests whether n1 and n2 are non-zero and if yes, performs the code after `if`; it treats n1 as zero/non-zero and uses `0<>` to convert n2 into a canonical flag; the `and` then produces an fz, which is consumed by the `if`.

You can use the all-bits-set feature of canonical flags and the bitwise operation of the Boolean operations to avoid `if`s:

```: foo ( n1 -- n2 )
0= if
14
else
0
endif ;
0 foo .
1 foo .

: foo ( n1 -- n2 )
0= 14 and ;
0 foo .
1 foo .
```

Assignment: Write `min` without `if`.

For reference, see Boolean Flags, Numeric comparison, and Bitwise operations.

Next: General Loops, Previous: Conditional execution, Up: Forth Tutorial   [Contents][Index]