ビット演算の使い方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
御津凪

ビット演算の使い方

#1

投稿記事 by 御津凪 » 17年前

雑談的な質問です。

初心者の方は知らないかと思いますが、
大体のプログラミング言語にはビット演算というものがあります。
( << , >> , & , | , ^ , ~ など)

皆さんはこれらを使用していますでしょうか?
(またはどのようなところで使用していますでしょうか?)

ビット演算は奥が深いもので、
フラグを立てる用途から2の倍数の乗除、
データの暗号化やハッシュ値生成など、意外と幅広い所で使われています。

どのように使っているか、というのが質問なのですが、
ここは初心者のための掲示板ですので、
出来ればわかるような説明が望ましいかもしれません。


私は、使えるところはバリバリ使う方です。

たとえば、ゲームに関連する処理で、ボタンの入力状態を返す時、
// ボタンを押した瞬間かどうかのフラグを返す
int ispush( int now, int prev ){return ((prev | now) ^ prev);}
// ボタンを押している間かどうかのフラグを返す
int ispress( int now, int prev ){return (now & prev);}
// ボタンを離した瞬間かどうかのフラグを返す
int ispull( int now, int prev ){return ((now | prev) ^ now);}
// ボタンを押していない間かどうかのフラグを返す
int isfree( int now, int prev ){return ~(prev | now);}

このようにしています。(ビット演算初見の方は 何じゃこりゃ!? と思いますね^^;)
これは int 値に入っているフラグをまとめて処理できるのでオススメです。
(DXライブラリのGetJoypadInputState()に使えると思います)

処理の意味を分かりやすくするため、
上記の関数をボタン一個に対しての判定に置き換えた場合も書いておきます。
// 押されている = 1 、押されていない = 0 とした場合

// ボタンを押した瞬間かどうかを返す
int ispush( int now, int prev ){return (now != 0) && (prev == 0);}
// ボタンを押している間かどうかを返す
int ispress( int now, int prev ){return (now != 0) && (prev != 0);}
// ボタンを離した瞬間かどうかを返す
int ispull( int now, int prev ){return (now == 0) && (prev != 0);}
// ボタンを押していない間かどうかを返す
int isfree( int now, int prev ){return (now == 0) && (prev == 0);}

という感じになります。

たかぎ

Re:ビット演算の使い方

#2

投稿記事 by たかぎ » 17年前

I/Oポートなど、ハードウェアを制御するときには普通に使います。
例えば、制御レジスタP0に、16ビットのI/Oポート(P00~P0F)が割り付けられている場合、
extern volatile unsigned short P0;
P0 |= 1 << 3;
とすれば、P03に1を出力できますし、逆に、
P0 &= ~(1 << 3);
とすれば、P03に0を出力できます。

他にも、CPUの状態(割り込み禁止やキャッシュなど)の制御や、周辺デバイスの制御を行うには必須です。
この手の分野に関わったことがない人にはさっぱり分からないかもしれませんが、これは初心者~初級者レベルの内容です。

管理人

Re:ビット演算の使い方

#3

投稿記事 by 管理人 » 17年前

私はマップチップのブロックみたいな情報によく使います。
上は進入可
下は進入不可
みたいな情報が4方向必要だったりすることがあるのですが、
その時は構造体でいちいち用意するのも勿体無いので各ビットを使います。

後はぷよ○よを作るとき、どちら方向にくっついているかという情報を格納するのにも使いました。

後、容量を小さくしたいとき、例えばリプレイデータなんかを使う時は
BYTE型でオンオフ情報をいれてたんじゃ勿体無いので、これもビットでやっています。
リプレイデータはほとんどが0で埋まると言う勿体無い構造をしてるので、きっとここで0を圧縮すると
いいと思うのですが、まだ龍神録では未実装です。
・・次回作では頑張ってみようと思ってますっ。

まぁ私もかなり使う方です。
JAVA使ってる友達がJAVAだと途端にビットシフト使わなくなったといってますが、そうなんですかね~?

御津凪

Re:ビット演算の使い方

#4

投稿記事 by 御津凪 » 17年前

> たかぎさん
ハードウェアの制御のほとんどはビット演算しやすい構造ですよね。
何かしら2の乗数に関連していますし。

> 管理人さん
Javaはクラスなどの構造体のサイズを意識することなく組める上、
フラグへのアクセスがプロパティとしてアクセスする形になっているので、
ビットシフトを使うとかえって見づらくなるからでしょうか。
(デザインパターンに合わないとか)

そういえば、 ^(XOR) を使った簡易暗号化というものがありましたね。
void crypt( const unsigned char* src, unsigned char* dest, int count, unsigned char seed ){
	int i;
	for(i = 0;i < count;++i){
		dest = src ^ seed;
	}
}

暗号化するデータに 一定の値で XOR 演算するという簡単なものですが、
復号化するのもまったく同じ演算で元に戻るという性質を利用しています。

lbfuvab

Re:ビット演算の使い方

#5

投稿記事 by lbfuvab » 17年前

そう言えば、私もライフゲームの盤面の保存の時に使った記憶がありますね。

ひよっこ

Re:ビット演算の使い方

#6

投稿記事 by ひよっこ » 17年前

「初心者は知らないと思う」というステレオタイプな考え方がイヤ。

閉鎖

“C言語何でも質問掲示板” へ戻る