false フラグはすべてのビットがクリアです(整数として通訳(interpret)される場合は 0)。 正規化された true フラグは、
すべてのビットがセットされています(2の補数の符号付き整数として -1)。 多くの文脈(例: if
)では、ゼロ以外の値はすべて true
フラグとして扱われます。
false . true . true hex u. decimal
比較ワードは正規化フラグを生成します:
1 1 = . 1 0= . 0 1 < . 0 0 < . -1 1 u< . \ 型エラー。 u< は -1 を 大きな符号なし数として扱ってしまいます -1 1 < .
Gforth は、接頭辞 0 u d d0 du f f0
(または「 接頭辞なし」)との比較 = <> < > <= >=
のすべての組み合わせをサポートします。 これらの組み合わせの一部のみが標準Forthです (詳細については、標準Forth または
Numeric comparison または Floating Point または Word Index
を参照してください)。
and or xor invert
を正規化フラグ用の演算子として使用できます。 実際には、 これらはビット単位演算です:
1 2 and . 1 2 or . 1 3 xor . 1 invert .
0<>
を使用して ゼロ/非ゼロ フラグを正規化フラグに変換できます(そして、 その途中で 0=
を使用して ゼロ/非ゼロ
フラグの余数(complement)を取ります。 実際、 正規化フラグでは invert
の代わりに 0=
を使用するのが一般的です)。
1 0= . 1 0<> .
0<>
無しでも if
で ゼロ/非ゼロ をテストすることはできますが、 ゼロ/非ゼロ 値を and or
xor
と組み合わせる場合、 and or xor
はビット単位での操作なので、 0<>
を使用する必要がある場合があります。 最も単純で、 エラーが少なく、 おそらく最も明確な方法は、 これらすべての場合に 0<>
を使用することですが、 場合によっては、 使用する 0<>
の数を減らすこともできます。 以下にいくつかのスタック効果を示します。
fc は正規化フラグ(canonical flag)を表し、 fz は ゼロ/非ゼロ を表します(すべての fc は
fz としても機能します):
or ( fz1 fz2 -- fz3 ) and ( fz1 fc -- fz2 ) and ( fc fz1 -- fz2 )
したがって、 以下のようなコードの場合:
( n1 n2 ) 0<> and if
これは、 n1 and n2 (n1 かつ n2)がゼロ以外であるかどうかをテストし、 イエスの場合は if
の後のコードを実行します。
n1 を ゼロ/非ゼロ として扱い、 0<>
を使用して n2 を正規化フラグに変換します。 and
は fz を生成し、
それは if
によって消費されます。
正規化フラグの全ビットセット機能とブール演算のビット単位の演算を使用して、 if
を回避することもできます:
: foo ( n1 -- n2 ) 0= if 14 else 0 endif ; 0 foo . 1 foo . : foo ( n1 -- n2 ) 0= 14 and ; 0 foo . 1 foo .
研究課題(assignment):
min
をif
無しで書いてみましょう。
こちらも参照下さい: Boolean Flags, Numeric comparison, Bitwise operations