重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

& | ~ ^のビット演算子はどんな場面で使いますか?

いまひとつ、ビット演算子が理解できません。

使いこなすには、二進数の表現、16進数の表現にも詳しくないとだめでしょうか?

ビット演算子を使わなければならない場面、ビット演算子を使うメリットを教えてください。

お願いします。

A 回答 (5件)

>ビット演算子を使わなければならない場面、ビット演算子を使うメリットを教えてください。



ビット演算は、整数型の中の特定ビットを操作するために使います。
主に8ビットや16ビットの中に、ビット単位の情報が複数パックされたものを操作する場面で使います。

具体的な場面として以下の2つを挙げます。
1.I/Oポートの読み書き
組込機器のプログラミング等で、マイコンチップに接続された機器はI/Oポートを介して制御します。
ある1本のピンのHigh/Lowは、I/Oポートの一つのビットの0/1に対応します。
外部のセンサーやスイッチの状態を知りたいときはそのビットを読み、逆に書き込みをすればLEDの点灯/消灯などをすることができます。
このようにI/Oポートを経由すれば外部とやりとりできますが、この
読み書きは1または2バイト単位で行います。つまり、ピン8本または16本まとめてということです。

このとき、目的のピンのみの情報を知るor書き込むときにビット演算が必要です。
具体的な操作は#2さんの例を良く理解してください。


2.画像データファイルの取り扱い
仮に1バイト=1ピクセルで赤3ビット、緑3ビット、青2ビットとか、
2バイト=2ピクセルで赤緑青共に5ビットで格納する形式があったとして、
各色の値を取り出すときはビットごとの操作が必要になります。


>& | ~ ^のビット演算子はどんな場面で使いますか?
& - 特定のビットを0にする、または特定のビットだけを取り出し他を0にする
| - 特定のビットを1にする
^ - 特定のビットを反転する
~ - 全部反転する
基本はこんな感じです。
これにシフトを組み合わせて色々な操作を行います。
#3さんの説明されているマスキングは非常に重要で基本的なテクニックです。
(data8 = (unsgined char)(data32 & 0xff);が正しい記述だと思いますが...(^_^;))


>使いこなすには、二進数の表現、16進数の表現にも詳しくないとだめでしょうか?
プログラムを作る人間なら知っていて普通であって欲しいことですし、詳しいとか詳しくないというレベルのことではないので、きちんと勉強してください。
単に10,2,16,8進数相互の変換ができればいいです。
最低限2進数<->16進数の変換ができればプログラムは書けなくもないです。
また、C言語では2進数形式でプログラムは書けないので、代わりに16進数表記で書くことになりますので、16進数には慣れておくと便利です。

>ビット演算子を使うメリットを教えてください。
メリットは特にありません。
ビット単位の操作を行うときには必ず使うものなので、メリットも何も..
足し算をするときに+演算子を使うようなものです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
どうも!
いろいろ詳しく書かれているので、たいへんに勉強になりました!
解りやすかったです!
どうもありがとうございます!

お礼日時:2006/12/18 17:54

#3さんの回答の前半は何を勘違いされているのかビット演算子については言及されておりませんので、


後半のビット演算子の典型的な無意味な使用例のみ参照されるとよいでしょう。
まぁ、気付くとは思いますが、typoも多いのでその点にもご注意を。

結論。使わなければならない場面に遭遇しない限り、積極的に使う必要はありません。
また、16進数の表現に馴れている必要は必ずしもありませんが、2進数の知識は不可欠です。
#尤も、それらはデバッグ時においても役に立つ知識ではありますが。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
右も左も解らない初心者なのでいろいろ参考になりました。
ありがとうございます。

お礼日時:2006/12/18 17:45

一般的にはbool変数を用いる祭に利用することが多いのがビット演算子だと思います。



bool Condition1, Condition2;
...
if (Condtion1 && Condition2) { // 状態1と状態2が同時に真なら
...
}
else if (Condtion1 || Condition2) { // 状態1と状態2のどちらかが真ならば
...
}
という具合で条件分岐の判定で利用する場合があります。

また具体的な事例では画像処理などにおいて
32ビットのデータを8ビットのデータに変換するときに利用します。

int data32;
unsigned char data8
data8 = (unsgined cahr)data32 & 0xff;

マスキングといって32ビットの変数にある値の下位8ビットのみを代入しています。
マスキングを忘れることで出力画像が予想しないものになる場合があります。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
コードの紹介ありがとうございます。
参考にします!

お礼日時:2006/12/18 17:42

組み込み系プログラマです。



ビット演算を使う例としてマルチタスク処理のイベントフラグを挙げます。8bitのイベントフラグがあって、次のようにイベントが割り当てられていたとします。
#define EVENT_1 0x01
#define EVENT_2 0x02
#define EVENT_3 0x04
#define EVENT_4 0x08
#define EVENT_5 0x10
#define EVENT_6 0x20
#define EVENT_7 0x40
#define EVENT_8 0x80
これらのイベントは複数のタスクから同時にセットされることがあり、イベントを取り出すときは一つずつ取り出して処理するものとします。

ここで、イベントフラグ event_flag にEVENT_1とEVENT_4が同時にセットされていたとします。具体的には event_flag = 0x09 という値になっていたとします。イベントフラグを読み出して処理を実行するタスクは、どうしたら event_flag に EVENT_1 が入っているかどうか判別できるでしょうか?

その答えは、ビット演算子の&を使って、

if( event_flag & EVENT_1 ){
  EVENT_1に対応した処理();
}

です。ビット演算子を使わなかったらどのような演算で判断するか考えてみてください。結構手間ですよね。

さらに、イベントフラグから EVENT_1 を消すには、

event_flag |= ~EVENT_1;

です。
分かりやすくするために筆算で書くと、
 event_flag = 0000 1001
 EVENT_1  = 0000 0001
なので、
  event_flag = 0000 1001
(or)~EVENT_1  = 1111 1110
--------------------------
  event_flag = 0000 1000
となり、EVENT_1 が消えます。

イベントフラグに限らず、(組み込みの世界で言えばハードウェアを制御するためのポートなど)1ビット単位で意味のあるものを扱おうとすると、必然的にビット演算を使います。

> 使いこなすには、二進数の表現、16進数の表現にも詳しくないとだめでしょうか?

ここで例としてあげた2進表現、16進表現が分かる程度の知識は必要です。

> ビット演算子を使うメリットを教えてください。

CPUは命令セットの中にビット演算を持っているものがほとんどなので、ビット演算は多くの場合1クロックで処理が終わります。これは大きなメリットだと思います。
    • good
    • 0
この回答へのお礼

回答どうもありがとうございます。
回答の内容にちょっとついていけないぐらいの初心者ですが、
将来参考になりそうです。
どうもありがとうございます!

お礼日時:2006/12/18 17:38

>& | ~ ^のビット演算子はどんな場面で使いますか?



FindFirst等で、ファイルの属性を調査、設定する場合に必須。

その他、ライブラリ関数には「1つの引数の各ビットに意味を持たせ、多数の情報を引数1つで渡す」「戻り値の各ビットに意味があって、多数の情報を戻り値1つで返す」と言う仕様の物が数多くあります。
    • good
    • 0
この回答へのお礼

すばやい回答ありがとうございます。
参考になります!
ありがとうございます。

お礼日時:2006/12/18 17:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!