ビットシフト演算

ご存知のように、コンピュータの中は、ONとOFFの二つの値から成る二進法で数が表現されています。OFFの状態は0と表現し、ONの状態は1で表現します。OFFは電位差がない状態、ONは電位差がある状態、という対応が普通だと思います。でも、1は1Vということじゃないようです、普通。

二進法のひと桁をビット(Bit)というわけで、32ビットパソコンだと、1単位(1セル)分で32個もの010110...という長蛇の列になるわけです。人を圧倒するには十分です....(^^;)。

ですが、機械の内部で使われている機構ですから、これを直接操作するのは、機械を直接操作することになって、間に余計なお世話を焼かれない分だけ効率が良くなります。

そこで、ビットデータを直接操作できるような低レベル言語では、これを好んでスイッチのように使います。いわゆるFlagというやつです。Mopsプログラミングでは、あまり似つかわしくない、というか、どういうわけか、ほとんど使いませんが、Mopsの内部機構としてはFlagは利用されています。また、API関数にFlagを渡す必要がある場合もあります。

以下、二進数のひと桁であるビットは、右から小さい順に並んでいるものと考えてください。

Flagは何桁目がONかOFFかという判定で決まるスイッチですから、桁の平行移動ができると便利です。例えば、1は、右端に1、残りは0ですから、これを、例えば15桁左に移動すれば、第16桁(右端を第1桁と決めたとして)だけが1、残りが0という状態を実現できます。まあ、32768と書きたければそうしても同じなんですが。なお、普通、桁は、第~ビットという名前で呼びます。で、右端は第0ビット、と0を出発点に数えます。ので、ここで第16桁と書いた桁は、普通のコンピュータ用語では、"第15ビット"と呼びます。

では、コンピュータ用語に則って、第15ビットだけがONの数値を得るには、
1 15 <<
とします。つまり、1を15桁左に平行移動、ですね。移動したときにできる右側の空所には、0が詰められます。

右に移動するのは">>"です。まあ、こういうことはしませんが、例としてやってみると、
1 15 <<
5 >>
とすれば、1を15桁左に移動したあと右に5桁戻してますから、第10ビットだけが1のFlagになります。値はもちろん1024です。この右移動も、移動でできた左側の空所には0が詰められます。

平行移動は、もちろん、1だけにしか適用できないものではありません。桁全体を平行移動します。はみ出した桁は、単純に捨てられます。移動でできた空所には0を詰めます。

10進数でひと桁上げれば10倍、ひと桁下げれば10分の1を意味するのと同じように、2進数では、ひと桁上げれば2倍、ひと桁下げれば2分の1になります。この機構が、速いかけ算-割り算のために使われているのです。

ただ、数値として考えると、正負を考慮しないといけません。コンピュータでの符号付き数値の表現法からみると、面白いことに、一番左端(第31ビット)が1なら負の数、0なら正の数に対応することがわかります。問題は右にずらすときで、負の数をひと桁右にずらして、左端にできた空所に0を詰めてしまうと、正の数値に変わってしまいます。つまり、負の数を半分にしたら、巨大な正の数になるわけです。

このように数値として処理する場合に対応して、右移動には、もう一つ便利なワードが定められています。それは"A>>"です。この右移動は、移動でできた左側の空所に、初めの値の左端が0だったときには0を、1だったときには1を詰めます。その結果、
-6 1 A>>
の結果は、"-3"になるわけです。まあ、">>"で負の数を移動してみるのも、興味があれば試してみてください。

なお、"<<"の同義語として"LSHIFT"、">>"の同義語として"RSHIFT"も定義されています。LSHIFT、RSHIFTはANS-Forth規格ワードです。

細かいことですが、一応注意を促したいことがあります。上では、数値の小さい桁の方を乗せるビットの方を小さい番号で表しました。数値との関係を考えるとそれが自然だと思うんですが、メモリーやレジスタとの関係では、実は逆の方が自然になります。というのは、メモリーのアドレスは、左から右へと大きくなって行くからです。つまり、PPCでは数値の中の小さい桁の方を、アドレス番号の大きい方に置くのです。そのようなわけで、IBMのPPCのマニュアルでは、ビット番号も左から小さい順に打ってあります。上とは逆です。例えば、4バイトの1は、上の説明では、第1桁=第0ビットだけが1で残りは0ということになりますが、IBM流では、第1桁=第31ビットだけが1で残りが0ということになります。


関連項目:






最終更新:2018年12月25日 14:36