Boolean型とUWSCのTrue/Falseについて

UWSCの仮掲示板で、True/Falseについて質問している人がいた。

そう、Boolean型だ。
ここでは、Boolean型の内部値について語りたい。

 

 

内部値って

コンピューターというのは0と1しか扱えないアホだ。
なんでも0と1にしてやる必要がある。
さて、Boolean型のTrueとFalseに内部値を割り当てよう。
0と1しか知らないなら、False(0)、True(1)で良いよね?

良いわけあるかい!
この割り当て、私は多いに「ふまんがあります」。

Falseが0なのは良いです。
何もなしだし。
でもTrue(1)はダメだ。
私にはビット演算とCPUのビット数という知識があるのです。
ビット演算的に0の反対は1。

 

ビット数とは

最近はスマートフォンも64bitCPUを積んでますね。
ちょっと前は32bit。
ちなみにファミコンは8bit。

なので、32bitなら0の反対は、1を32個並べろよ、と言いたい。
でまあ、それは「2の補数」として解釈され、結果-1。
そう、False(0)の反対は、True(-1)。
個人的には、異論は認めたくない(やや弱気)。

 

論理演算とビット演算

でも、論理演算とビット演算、同じように動いて欲しいですよね。
もしですよ、True(-1)にすると、ほぼ同じように動くんですよ。

True = Not False
-1 = ! 0

True = True Or False
-1 = -1 | 0

True = True And True
-1 = -1 & -1


しかも、人間の感覚的に、0以外はTrueってのもある程度納得できるじゃないですか。
ここにも矛盾が出にくい。
まあ、Not/Xorはほとんどダメなんだけど、Orは大丈夫だし、Andも部分的に救える。
2 & 1 = 0 はダメだけど、
3 & 1 = 1 でOKだね。

ビット反転は、-1以外は全て0以外になるのでダメだし、
ビットXORは、同値以外は全て0以外になってしまう。

とはいえ、&に関しては、True(-1)と数値で&を取るなら、0以外は0以外になるので、かなり救える幅が広がる。
なので、-1にするしかないのですよ!

 

UWSCの現状

UWSCでは、0はFalse、0以外はTrueになる。
過去互換性もあって、Trueは内部値1だけど、変換でBooleanを作った場合は、内部値-1になる。
MSGBOX(VARTYPE(VARTYPE(1, VAR_BOOLEAN), VAR_DOUBLE)) // -1

過去互換性なんかぶったぎって、True(-1)にして欲しかったなぁ。

MSGBOX(True AND 2) // 0
はなんかね。
MSGBOX(VARTYPE(1, VAR_BOOLEAN) AND 2) // 2
なら「2」となり、IF文でTrueに入れる。

等号などの比較演算子は、定数と同じTrue(1)やFalse(0)を返します。
等号では、True(1)もTrue(-1)も、両方BOOL型の場合はTrueとして扱われるため、True(1)になります。
MSGBOX(VARTYPE(1, VAR_BOOLEAN) = True) // 1、True(1)の内部値が表示される
しかし、片方が数値になると内部値で評価されます。
これは大なり・小なりなどの関係演算子も同じです。
MSGBOX(VARTYPE(1, VAR_BOOLEAN) = -1) // 1
MSGBOX(VARTYPE(1, VAR_BOOLEAN) < 1) // 1
MSGBOX(VARTYPE(1, VAR_BOOLEAN) < TRUE) // 0。Boolean同士なら大小はないみたい
MSGBOX(VARTYPE(1, VAR_BOOLEAN) <= TRUE) // 1。Boolean同士なら大小はないみたい

AND や XOR では以下のようになります。
MSGBOX(VARTYPE(1, VAR_BOOLEAN) AND TRUE) // 1
MSGBOX(VARTYPE(1, VAR_BOOLEAN) AND VARTYPE(1, VAR_BOOLEAN)) // -1
MSGBOX(VARTYPE(1, VAR_BOOLEAN) XOR TRUE) // -2
MSGBOX(VARTYPE(1, VAR_BOOLEAN) XOR VARTYPE(1, VAR_BOOLEAN)) // 0
なんと、True(-1)とTrue(1)のXORは、-2です。
これ、IF文に渡すと、Trueとして評価されるので、論理演算として見た場合は期待動作ではないですね。