7月15日オンライン分

ビット演算(ビット操作)

ビット毎の計算、フラグ処理などにつかう。

1 0 1 0 1(2) => 10進数だと? ()内は基数
16  4   1    => 16+4+1=20(10) 
フラグ(flag)
🏳旗の事、旗の上げ下げで状態を表す  
スイッチのON/OFFだと思って良い  
ON:旗を立てる=>フラグを立てる
OFF:旗を下げる=>フラグを下げる
フラグを変数としてあらわすには?

 →bool(ブール型(ブーリアン))を使うとよい

→変数名には、isXXXXにするとフラグ変数だよ、とわかりやすい\\

  例)ライフがまだ残っているかいないかというフラグ(life<0にフラグが立つ=死亡フラグ)

isDead = true;//←死亡フラグON
isDead = false;//まだ生きている
    isDead = false; //初期化=>初めは必ず生きている
  while(isDead == false)
    {
       //敵と戦う処理
       //lifeが増えたり、減ったり
       if(life < 0)isDead = true;
    }
 
    cout << "ゲームオーバー" << endl; //ゲームオーバーの処理をして、プログラムを終了
 
 \\

 →あまりフラグ変数が増えすぎるとプログラムがわけわからなくなるよ。
  でも割と使う。。。

  例)脱出ゲーム
    A~Fのアイテムをゲットしてある。
    G~Hの謎をすべて解いてある。
    仲間I、J、Kを助けている。
    これらのすべての条件を満たした場合だけ、無人島から脱出できる

bool isGetItemA = false;//   アイテムAを取ったかどうか 
bool isGetItemB = false;//   アイテムBを取ったかどうか
bool isGetItemC = false;//    アイテムCを取ったかどうか
bool isGetItemD = false;//   アイテムDを取ったかどうか
bool isGetItemE = false;//   アイテムEを取ったかどうか
bool isGetItemF = false;//   アイテムFを取ったかどうか
bool isSolveG = false;//     謎Gをといているか
bool isSolveH = false;//     謎Hをといているか
bool isHelpI = false;//      仲間Iをたすけているか
bool isHelpJ = false;//     仲間Jをたすけているか
bool isHelpK = false;//     仲間Kをたすけているか
bool isGameClear = false; // ゲームクリアかどうかの判別フラグ
 
フラグのtrue falseif文を書いて処理を分岐させる
	if(isGetItemA && is GetItemB && ..... isHelpK){
	  isGameCelar = true;\\
	}
bool型(true,false)のメモリサイズって?

  ここでちょっとした疑問、理論的には、フラグは上がってるか下がってるか(立ってるか、立ってないか)
しかないので、1ビット(0 or 1)で表現できる。(0が偽(フラグOFF)、1が真(フラグON))
その真偽を表す bool型(true,false)のメモリサイズって?

boolは、標準では変数1個当たり2byteとされている。
1個当たり2byte(16bit)

     なので、フラグ12個で24byte(192bit)のメモリを使う! \\
     0 or 1で表せるはずなのに… \\
ビットフラグの発想

そこで、フラグを12bitの0と1の羅列(2進数)で表して、以下のように対応付ける(コメント部)

//bool型のフラグと、ビット位置の関係
bool isGetItemA = false;//右から0ビット目 アイテムAを取ったかどうか \\ 
bool isGetItemB = false;//   1ビット目 アイテムBを取ったかどうか\\
bool isGetItemC = false;//   2ビット目  アイテムCを取ったかどうか\\
bool isGetItemD = false;//   3ビット目 アイテムDを取ったかどうか\\
bool isGetItemE = false;//   4ビット目 アイテムEを取ったかどうか\\
bool isGetItemF = false;//   5ビット目 アイテムFを取ったかどうか\\
bool isSolveG = false;//    6ビット目 謎Gをといているか\\
bool isSolveH = false;//    7ビット目 謎Hをといているか\\
bool isHelpI = false;//     8ビット目 仲間Iをたすけているか\\
bool isHelpJ = false;//     9ビット目 仲間Jをたすけているか\\
bool isHelpK = false;//    10ビット目 仲間Kをたすけているか\\
bool isGameClear = false; // 11ビット目 ゲームクリアかどうかの判別フラグ\\    

フラグ設定例:
初期状態?
000000000000(2)(12bit) =(そのまま整数に変換すると)⇒ 0(10)

アイテムAとBとDだけ取った後(クリアは条件を満たしていない)
000000001011(2) =(そのまま整数に変換すると)⇒ 11(10)

アイテムはすべて取って、仲間J,Kを助けた状態は?
011000111111(2) =(そのまま整数に変換すると)⇒ 1599(10)
カッコ内は基数(何進数であらわされているか)

ちなみに2進数と10進数を変換してみると、

                         0       1     1     0      0    0   1  1 1 1 1 1
         8192   4096  2048   (1024) (512) (256)  (128) (64) 32 16 8 4 2 1
         
	1024 + 512 + 32 + 16 + 8 + 4 + 2 + 1 = 1599(10)
- - bit 11 bit 10 bit 9 bit 8 bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
- - 0 1 1 0 0 0 1 1 1 1 1 1
8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1

1024 + 512 + 32 + 16 + 8 + 4 + 2 + 1 = 1599(10)
なので、011000111111(2)は符号なしの10進整の数値をつかって1599で表現できるんでないかな?
でも、12ビットの整数型なんて聞いたことないよね?
しかたないから、12bit以上の整数の型に入れちゃえばよくない?
昔習った型を振り返ってみる
今使いたいものは、符号なしの2進数なので以下のものが使えないかな?と考えてみる。

char → 1byte(8bit) x少ないなぁ
short → 2byte(16bit)行けそう!
short以上の幅の整数型なら、12bit以上のフラグを扱える。
ちなみに、
int→4byte(32bit)だとビットありすぎ

short myFlag = 0; \\2byteの変数を準備
0000|000000000000 で初期化
|→こっから右がフラグ
bool 2byte
unsigned は符号なしの意味
unsigned char 1byte(8bit) \\  unsigned short 2byte(16bit)
unsigned int 4byte(32bit)