ビット演算はどういう時に使えばいいのでしょうか?
演算の意味は理解しましたが、使いどころが分かりませんでした。
抽象的な質問ですが、よろしくお願いします。
http://dixq.net/sm/w2.html
質問とは関係ありませんがこのページが文字化けして正常に表示されません。
エンコードを変更してみましたが、文字化けは直りませんでした。
新しいトピックを立てるわけににもいかなかったので、ここで報告しました。
ビット演算子について
Re:ビット演算子について
2の乗数の乗除を、シフト演算で代替することで高速化を図ることができたり、
DirectX 等のカラー情報から特定の色情報だけを取り出しや置き換えなどが出来たり、
簡易的な暗号化を施したり…などが上げられます。
こうして挙げると、主にビットを扱う程度の処理で使用するのが多いですね。
なので、普段はあまり全ての演算子を扱うことが少ないです。
ゲームなどの実用的な方法として、たとえば、
DirectX 等のカラー情報から特定の色情報だけを取り出しや置き換えなどが出来たり、
簡易的な暗号化を施したり…などが上げられます。
こうして挙げると、主にビットを扱う程度の処理で使用するのが多いですね。
なので、普段はあまり全ての演算子を扱うことが少ないです。
ゲームなどの実用的な方法として、たとえば、
#define FLAG_COUNT 1024 // フラグ数 static unsigned long sFlagData[FLAG_COUNT >> 5]; // フラグデータ // 指定した位置のビットフラグを取得 // id は取得するビット番号、戻り値はそのフラグ値。 int get_flag( int id ){ return (sFlagData[id >> 5] >> (id & 31)) & 1; } // 指定した位置のビットフラグを立てる // id は立てるビット番号 void set_flag_on( int id ){ sFlagData[id >> 5] |= (1 << (id & 31)); } // 指定した位置のビットフラグを降ろす // id は降ろすビット番号 void set_flag_off( int id ){ sFlagData[id >> 5] &= ~(1 << (id & 31)); }このようにフラグを省スペースで管理することが出来ます。
Re:ビット演算子について
なるほど、構造体を用意してフラグを管理しなくてもすみますね。
ビット演算は処理が高速と聞いていたので、何らかの計算に使用するイメージがありました。
サンプルコード参考にします。
>2の乗数の乗除を、シフト演算で代替することで高速化を図ることができたり
暗号化は興味があるので調べてみます。
回答有難うございました。
ビット演算は処理が高速と聞いていたので、何らかの計算に使用するイメージがありました。
サンプルコード参考にします。
>2の乗数の乗除を、シフト演算で代替することで高速化を図ることができたり
num = 5 * 5; num = 5 << 1;こういうことですよね。
暗号化は興味があるので調べてみます。
回答有難うございました。
Re:ビット演算子について
5 * 5 と 5 << 1 では計算結果が違いますよ。
5 << 1 は 5 * 2 と等価です。
X << N と変数で考えた場合、
X を 2 の N 乗で掛ける、と覚えておくと分かりやすいかと思います。
あと、他にビット演算でよく使われるアルゴリズムとして、
圧縮や解凍、画像処理、ハッシュ、ランダム値生成などがあります。
5 << 1 は 5 * 2 と等価です。
X << N と変数で考えた場合、
X を 2 の N 乗で掛ける、と覚えておくと分かりやすいかと思います。
あと、他にビット演算でよく使われるアルゴリズムとして、
圧縮や解凍、画像処理、ハッシュ、ランダム値生成などがあります。
Re:ビット演算子について
お恥ずかしい、勘違いしてました。
>X << N と変数で考えた場合、
>X を 2 の N 乗で掛ける、と覚えておくと分かりやすいかと思います。
よく覚えておきます。
勘違いしたままプログラムを組むところでした。
>X << N と変数で考えた場合、
>X を 2 の N 乗で掛ける、と覚えておくと分かりやすいかと思います。
よく覚えておきます。
勘違いしたままプログラムを組むところでした。
Re:ビット演算子について
マイコンではよく使います。マイコンにはポートと呼ばれる入出力するためのアドレスが
あります。この各ビットにスイッチやLEDやモータをつなぎます。
例えば、スイッチ4個をポートの下位4ビットに接続した場合、B0のスイッチが押されて
いるか調べるときに0x01と&します。これをマスクといいます。
8個LEDをつないで、ナイトライダーの車のようにLEDを順番に転倒させたりしたものです。
(ナイトライダーって知ってる人?いる?)
こんなとき、シフトを使います。
あります。この各ビットにスイッチやLEDやモータをつなぎます。
例えば、スイッチ4個をポートの下位4ビットに接続した場合、B0のスイッチが押されて
いるか調べるときに0x01と&します。これをマスクといいます。
8個LEDをつないで、ナイトライダーの車のようにLEDを順番に転倒させたりしたものです。
(ナイトライダーって知ってる人?いる?)
こんなとき、シフトを使います。
Re:ビット演算子について
ナイトライダーは分かりませんが、マスクとシフトのプログラムを書いてみました。
また勘違いしているかもしれません。合っているでしょうか?
また勘違いしているかもしれません。合っているでしょうか?
if(PORT_ADRESS & 0x01) //B0のスイッチが押されている for(int i=0; i < 8; i++) PORT_ADRESS = 0x01 << i;
Re:ビット演算子について
>8個LEDをつないで、ナイトライダーの車のようにLEDを順番に転倒させたりしたものです。
ナイトライダー・・・ なつかしいw
車が喋ったりジャンプしたり、久しぶりに見たくなりましたw
ナイトライダー・・・ なつかしいw
車が喋ったりジャンプしたり、久しぶりに見たくなりましたw
Re:ビット演算子について
0と1の信号がいくつかセットになってるような場合によくビット単位で使いますよね。 例えば「ゲームのコントローラーのキー入力状態」 0なら押していない 1なら押している こうしてキー入力をチェックしたりよくします。 1バイトは8ビットなので、1バイト用意するだけで、8個も0と1を入れる入れ物が用意出来るわけです。 今コントローラーの各キーが以下のように各ビットに対応しているとします。 下 上 左 右 A B L R [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] このように対応しているとして、今Lキーが入力されているとすると 下 上 左 右 A B L R [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 0 ] [ 1 ] [ 0 ] こんな感じになるわけですね。 2進数で00000010は10進数で言う2ですが、そういう考えはせず、 「右から2番目のビットがたっているか?」という感じで判定していきます。 こうすることで、いちいち変数を用意するより少ないスペースで効率よく判定出来るわけです。
Re:ビット演算子について
>また勘違いしているかもしれません。合っているでしょうか?
あってますよ。
スイッチはマイコンの場合、回路を簡単にするため、ONのとき0になる
回路を作ることが多いです。ですから、
if(~PORT_ADRESS & 0x01)
のように反転させることがよくあります。
あってますよ。
スイッチはマイコンの場合、回路を簡単にするため、ONのとき0になる
回路を作ることが多いです。ですから、
if(~PORT_ADRESS & 0x01)
のように反転させることがよくあります。