ビット積と、ビットのコントロール

ウディタ講座&テクニック「ビットを使いこなす編」第2回

ビット積と、ウディタで「ビット」を使うためのコントロール方法(変数操作方法)について解説します。

前回に引き続き、2進数を扱うお話です。2進数?なにそれ?という方は、こちらをご覧ください。

前回はウディタの「ビットを満たす」とはどういうことなのかを解説しました。

そして今回は変数操作の、右辺同士をつなぐ演算子「ビット積(論理積)」の解説と、ウディタ上でのビットコントロール方法(変装操作方法)について解説します。

ビット積とは

ウディタの変数操作では、主に代入先、代入演算子(=とか +=とか)、右辺1、右辺同士の演算子、右辺2を指定します。

ここでは、代入先と代入演算子はひとまず置いておいて、右辺1&2をつなぐ演算子「ビット積(論理積)」を解説します。

まず、ウディタにおけるビット積とは何か を言ってしまいますと、『両右辺を2進数に直して、各ビット同士で掛け算をする という演算方法』です。

ではサンプルコードも交えつつ、詳しく見ていきましょう。

▼ EvSelf[0]に、5と3のビット積が代入される ■変数操作: このEvのセルフ変数0 = 5 論理積 3

サンプルコードで使用された数値、「5」と「3」を2進数に直して、各ビットごとに掛け算をしてみます。

それぞれを2進数で表すと、5=「101」 3=「011」ですね。

  • 1のビット:1x1=1
  • 2のビット:0x1=0
  • 4のビット:1x0=0

5と3をビットごとに掛け算した結果は、1のビットだけが1になり、他のビットは0になりましたね。

というわけで計算結果「001」が代入先であるEvSelf[0]に代入されることになります。

このビット積という演算方法の特徴としては、各ビットごとに「0 or 1 の掛け算」になるわけですから、「両方が1なら1、どちらかが0なら0」になる所です。

つまり右辺1と2、両方の数値に含まれるビットだけが「1」として残ることになります。

今回の例でいえば、5と3 両方に含まれるビットは「1」のみだったというわけです。この例だけでは難なので、他の例もまとめて見てみましょう。

ビット積の例

21(10101)と13(1101)のビット積の例

51(110011)と17(10001)のビット積の例

58(111010)と43(101011)のビット積の例

ここまでで、ビット積のイメージがつかめたでしょうか?

2進数の仕組みが分かっていて、特定のビットを満たすということは、その桁が「1」になっているということだな。ということが分かっていれば、難しいものではなかったのではと思います。

案外10進数と2進数の変換が一番大変だったりしますね^^;

「0か1」という表現について

さて、ビットのコントロール方法の解説の前に、少し脱線してお話しなければならないことがあります。

ここまでで解説した通り、2進数の各桁(ビット)は必ず0か1 どちらかの状態になっています。これが何を意味しているか、を少し考えてみましょう。

0か1で表現できることって色々あると思うのですが、ウディタでは以下のようなものをよく使うのではないでしょうか?

Yes(1) or No(0)

例えば、特定のキャラクターがパーティにいるかどうか?とか、特定のEvは終了しているかどうか?とか。

このYesNoに似たような表現として、True(1) or False(0)というものもあります。多少プログラミングに詳しい人なら、こっちのほうがよく使うかも知れませんね。

On(1) or Off(0)

特定のスイッチの状態を管理するときや、機能の有効(1)/無効(0)の切り替えなんかによく使うかと思われます。

こういったものをひっくるめて、俗に「フラグ」なんて呼んだりしていませんか?

これらの表現は、そのまま2進数の各桁(ビット)にも当てはめることが出来て、たとえば10進数「5」を例にすると……

10進数「5」を2進数に直す
4のビット2のビット1のビット
101

この2進数「101」を見たときに、『1のビットがONになっている』『2のビットはOFFになっている』『4のビットはTrueだ』などと言うことが出来ます。

プログラミング業界では、この「1」になっている状態を『ビット(≒フラグ)が立っている』などと表現することもあるようです。

ウディタでいう『ビットを満たしている』というのも、この0か1かを表す表現の1つだったわけです。

今このお話をしたのは、解説で使う表現をある程度統一するためです。

というわけで、これ以降の解説において 特定のビットの状態を表す表現はOn(1)とOff(0)、およびウディタでの表現「満たす」を使っていきます。

1のビットが「1」とか よくよく考えたら紛らわしかったですよね。

混乱を招かないようにここで統一するべく このお話をしたのですが……ちゃんとついて来れたでしょうか^^;(逆に混乱させていたとしたらゴメンなさいね)

広告

ビットコントロール:特定のビットをOn(1)にするには

ようやくビットコントロール(ビットを使うための変数操作方法)のお話です。

ウディタでビットを使うためには、ビットの管理用変数 を用意する必要があります。この管理用変数は、ウディタ上では普通に10進数での表記ですが、脳内で2進数に変換しながら扱うことになります。

今回の解説では、ウディタの通常変数0番に『ビット管理用変数』と名前を付けて扱うことにしましょう。下記サンプルコードをご覧ください。

■変数操作: V0[ビット管理用変数] = 0 + 0

まず、分かりやすいように 管理用変数を初期化しました。この時点では管理用変数には「0」が代入されています。

管理用変数は2進数として扱わなければならないので、代入された10進数の「0」を2進数的に解釈しましょう。つまり管理用変数は現在『すべてのビットがOff(0)の状態』だということです。

では、特定のビットをOn(1)にしてみます。とりあえず1のビットをOnにしてみましょう。

■変数操作: V0[ビット管理用変数] += 1 + 0
現在の通常変数0番[ビット管理用変数]の状態:10進数で「1」
・・・16のビット8のビット4のビット2のビット1のビット
00001

次は16のビットをOnにしてみます。

■変数操作: V0[ビット管理用変数] += 16 + 0
現在の通常変数0番[ビット管理用変数]の状態:10進数で「17」
・・・16のビット8のビット4のビット2のビット1のビット
10001

次は2と4のビットをまとめてOnにしてみましょうか。

■変数操作: V0[ビット管理用変数] += 6 + 0
現在の通常変数0番[ビット管理用変数]の状態:10進数で「23」
・・・16のビット8のビット4のビット2のビット1のビット
10111

※2と4の両方のビットを満たす数値「6」を足すことで、2と4のビットをまとめてOnにしている。


……こんな感じで、Onにしたいビットを満たす数値を足すことで、そのビットをOnにすることが出来ますね。

しかし、気を付けなければいけないことがあります。それは、代入先のビットの状態が分からない場合です。

下記コードをご覧ください。

■変数操作: V0[ビット管理用変数] = 0 + 0 ■変数操作: V0[ビット管理用変数] += 1 ~ 7

ここに 特定のビット、ここでは4にしましょうか。4のビットをOnにするための加算を行うとします。

■変数操作: V0[ビット管理用変数] += 4 + 0

この時、ビット管理用変数が もともと4のビットがOffの状態だったら何の問題もありません。しかし問題なのは、4のビットがOnの状態の所に4を足してしまうことです。

ここでの例で言えば、1~7の乱数の時に4のビットを満たす数値 すなわち5,6,7のいずれかが 管理用変数に代入されていた場合です。

  • 5+4=9
  • 6+4=10
  • 7+4=11

加算結果の数値、9,10,11を2進数に直すと分かるのですが、すべて4のビットがOffになっています。

そうです。特定のビットがOnになっている所に さらにそのビットをOnにするために数値を加算してしまうと、そのビットはOffになってしまいます。

問題なのはそれだけではなく、繰り上がり(2進数:1+1=10)が発生して 他のビットの状態まで変えてしまうのです。

これを避けるためには、2つの方法があります。

  • 数値を加算する前に「~のビットを満たす」の判定を入れて『満たさない』の時だけ加算をする。

  • 数値を加算する前に、あらかじめその特定のビットをOffにしておく

2番目の方法で、『特定のビットをOff(0)』にするというのがありますね。次はこれの方法を解説します。

ビットコントロール:特定のビットをOff(0)にするには

On(1)にするときと反対のことすればOKなわけですから、その特定ビットを満たす数値を減算すればいいのです。

しかしOn(1)にする時と同様、注意しなければいけないのは もともとOffになっているのに、Offにするための減算を行ってしまうこと。

今度は繰り下がりが発生してしまいます……

これを避けるためには やはり条件分岐で『~のビットを満たす』判定で『満たす』場合のみ減算を行う……という処理をするしかないように思えますが、そんなことはありません。

ウディタでは、代入先のビット状態に関わらず、特定のビットを確実にOnにする演算方法というのはありませんが、特定のビットを確実にOffにする演算方法ならあるんです。

その演算方法とは、ずばりこれです。

▼ 分かりやすいように、通常変数1番にも名前を付けました。 ■変数操作: V0[ビット管理用変数] -= V0[ビット管理用変数] 論理積 V1[Offにしたいビットを満たす数値]

管理用変数の現在の数値Offにしたいビットを満たす数値ビット積を引くのです。

先ほど学んだばかりのビット積がここで役に立ちます!

これは実際に計算してみると分かるのですが、管理用変数のビット状態がどうであれ 確実に特定のビットをOffに出来ます。

では、管理用変数のビット状態がどうであれ、6(2と4)のビットをOffにしたいという場合の例を見てみましょう。

ご覧のとおり、Offにしたいビット以外にはまったく影響を与えずに、なおかつ元々のビットがOnだろうがOffだろうが 確実安全にOffに出来ます。

先ほど、代入先のビット状態に関わらず、特定のビットを確実にOnにする演算方法はない と言いましたが、この計算と組み合わせることで、特定のビットを確実にOnにする演算方法を疑似的に再現できます。

■変数操作: V0[ビット管理用変数] -= V0[ビット管理用変数] 論理積 V1[Onにしたいビットを満たす数値] ■変数操作: V0[ビット管理用変数] += V1[Onにしたいビットを満たす数値] + 0

まず、Onにしたいビットを確実安全にOffにしたうえで、改めてOnにするための加算を行えばOKというわけです^^

まとめ

  • ビット積とは、ある2つの数値(ウディタでは右辺1&2)を2進数にして、各桁(ビット)ごとに掛け算をする演算方法である。

  • ビット積を利用することで、特定のビットを確実安全にOffにすることが出来る。

  • 特定のビットをOnにしたい場合は、Onにする処理の前に、Offにする処理を入れておけば安全。

ビット積と、それを利用したビットコントロール(変数操作方法)までざざっと解説しましたが、如何でしたか?ちょっと難しかったでしょうか?

ウディタでビットを使いこなそうと思ったら、2進数の理解と、ビットOn/Offの方法を知っている必要があります。にしても、今回の解説記事はちょっと詰め込み過ぎたような気がしないでもないですが……^^;

余談ですが、特定のビットを確実にOnにする演算方法は『ビット和』と言って、[101]+[011]=[111]みたいに、どちらかのビットが満たされていればOnになる というものです。

残念ながらウディタ(ver.2.21時点)には実装されていない演算方法なので、まずビット積を使ってOffにしてから、改めてOnにする。という方法で疑似的にビット和を再現する必要があるんですよ。

さて、次回はいよいよ ウディタでビットを活用する『実践的』解説になります。お楽しみに!

アザー


広告

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA