• ベストアンサー

ビットシフトってどんな時使うの?

<<を使うビットシフトってありますよね? あれってどういうとき使うんでしょうか・・。 使い方が良く解りません。 10進数の2を8に出来たりするようですけど 2を8にしたり 2を32にしたりする事って便利なんでしょうか? それとももっと他の使い方があるのでしょうか? ビットシフトを利用した便利な使い方、なぜこのような使い方があるのか教えてくださいお願いします!^^

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

掛け算、割り算の代わりに使う事ができます。 ある数を2倍にする時、通常「data*2」としますよね。 これを「data<<1」としても同じ事になります。 同様に data<<2:4倍 data<<3:8倍 data<<4:16倍 逆も出来ます。 data>>1:1/2 data>>2:1/4 data>>3:1/8 こちらの方が普通に掛け算するよりも演算速度が速いそうです。

その他の回答 (6)

  • matyrcry
  • ベストアンサー率47% (101/213)
回答No.7

確かに単体では使いどころの難しい演算ですね。 乗除算をシフトと加減算の組み合わせで実現したので、CPU自体に そういう命令語を持っています。 もっと高等な(人間の思考回路に近い)命令語もたくさんあるので、 それで足りれば使う必要もないと思いますが、その処理を実現するた めにCPU内部で行われている手順に思いを巡らせてみれば、シフト を使っている部分が多々あるはずです。 CPU内部で実際に使われる部品(演算)に近いものなので、うまく 使えば、高等な部品を使うのと比べて無駄なく速く処理できます。 たとえば、printf("%x",○○○) は4ビットシフトとANDで4ビッ トづつ切り出して文字列を自作すれば、printf()という汎用変換関数 でを使うよりはかなり速く処理できます。 "%x"が固定でやることが決まっていての話ですが。 内部で実行されている手順のうち、必要最小限なものだけを抽出しよ うとして、手順を細かく分解していくと、行き着く先にシフト命令が あるわけです。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

一番分かりやすいのは、8ビットの値を2つ使って16ビットの値を作るような場合です。 具体例を書くと、 unsigned char high = 0x12; unsigned char low = 0x32; unsigned short word = high << 8 | low; のような使い方をします。 逆に、16ビットの値から上位8ビットと下位8ビットを分離するには、 unsigned short word = 0x1234; unsigned char high = word >> 8; unsigned char low = word & 0xff; のようにします。 こうした処理は、通信プロトコルやバイナリファイルを扱うときは普通に使うので、必要に迫られれば自然に理解できると思います。

回答No.4

やはり、ハードウエアよりの話ですが、シリアル―パラレルの変換にも使われますね。 シリアルというのは、データがひとつの信号線から、 010101101010110111 のように、順次流れてくる形式。 これを、最終的には(たとえば、メモリに書き込む、ハードディスクに書き込むなど)8個なり16個なり32個の固まりで行う必要があります。 これをたとえば、 0 -> 00000000(1ビット受信して右シフト) 1 -> 10000000(以下同じ) 0 -> 01000000 1 -> 10100000 1 -> 11010000 1 -> 11101000 0 -> 01110100 1 -> 10111010 8個そろったので、10111010 をまとめて送り込む というような処理をします。

  • moritan2
  • ベストアンサー率25% (168/670)
回答No.3

ビットシフトを使うことはハードを直接さわるプログラミングでは必須です。用途は数え切れませんが、一例をあげれば、たとえばゲーム機で16ビットカラー ARGB1555のデータから、たとえば赤を取り出す時は red = (color >> 10) & 0x1f; とかします。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

マイコン制御プログラムの実例を挙げます。 あるマイコンでは12bitの精度を持つAD変換を行った結果が16bitのレジスタの上位から埋まっていきます。このとき、下位4bitにはAD変換とは関係ない値が入っています。16bitのレジスタから意味のある上位12bitだけを取り出すために、 value = AD.DAR >> 4; というふうにビットシフトを使います。

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.1

1)ビット状態の判定や、ビットのセット(TestBit |= CheckBit) 等に使います。 unsigned char CheckBit; unsigned char TestBit; int jj; TestBit = xxxx; // 任意のビット値をセット CheckBit = 0x1; for(jj = 0; jj < 8; jj++){ if((TestBit & CheckBit) != 0) { printf("Bit %d On\n", jj); } CheckBit <<= 1; } 2)ビットパターンの合成・分割 unsigned int TestDat; unsigned char HighBit; unsigned char LowBit; TestDat = 0x12 + (0x34 << 8); HighBit = (TestDat & 0xff00) >> 8; LowBit = TestDat & 0xff; 3)暗号化・暗号の復号化

関連するQ&A

  • ビットシフトについて

    12ビットのデータ(符号付き)を16ビットのデータに変換したいです。 自分なりに考えたのですが・・・ 最上位ビット(符号を表すビット)の位置が違うので左に4ビットシフト、 右に4ビットシフトします(どちらも算術シフトとします) 例  0000 1011 1101 0101 (12bit のデータ) →1011 1101 0101 0000 (左にシフト) →1111 1011 1101 0101 (右にシフト) こうするとたしかに16ビットのデータの最上位ビットには12ビットのデータの符号が 反映されるように思えるんですが、符号を除いた値そのものが変わってしまいますよね? どうしたらいいでしょうか 切羽詰まってて文章めちゃくちゃで分かりづらいかとは思いますが、解答よろしくお願いします。

  • マスク処理・ビットシフト教えてくださいっ!

    10文字入る文字型配列aaを、ビットの列と考える(全部で80ビット)、この配列のビットを先頭から0ビット目、1ビット目、・・、79ビット目と数えると、 0ビット目:aa[0]の0ビット 7ビット目:aa[0]の7ビット 9ビット目:aa[1]の1ビット 17ビット目:aa[2]の1ビット では、nビット目は「aa[S]のRビット」とした時、SとRをビット操作でnを用いてどのように求めればよいか今までの課題と同様に答えなさい。 マスク処理する場合には、AND 0x00F0のように書き、ビットシフトする場合にはシフトするビット数をnからどのようなビット処理で求めるかを書くこと。 この問題が分からなくて困っています…! 教えてくれる方いらっしゃいませんか?

  • シフト演算の左シフトが何で72になるのでしょうか?

    ■やりたいこと ・100を左に1ビット(1けた)シフトさせたら2倍になることを確かめたい ■試したこと ・100を2進数へ変換 → 1100100 ・左に1ビット(1けた)シフト → 1001000 ・1001000を10進数へ変換 → 72 ■質問 ・どこで間違えているのでしょうか?

  • シフト演算について

    基本情報技術者試験の資格試験のための勉強をしているものです。 現在、カテゴリー的には基礎理論の離散数学、 シフト演算のうち、「論理シフト」ではなく、 「算術シフト」で理解できない点があります。 左シフトは理解できたつもりなんですが・・・ 右シフトがいまいちよくわかりません。 以下に例題を表記します。 【10001100を2ビット左シフト】 先頭ビットは符号ビットということで、マイナスの数値になるのだと思います。すると、 【元の数】 10001100 =-(0001100) =-(8+4) =-12 【2桁左シフト結果=元の数×2^2】 10110000 =-(0110000) =-(32+16) =-48 となり、 元の数=-12 結果 =-48 で、結果が元の数×2^2で結果が合っているようです。 (と思っているだけなんですが) 元の数の考え方自体に間違いがありそうですが・・・ とりあえず進みます。 同様に 【10001100を2ビット右シフト】すると 【2桁右シフト結果=元の数×2^-2(=元の数×1/4)】 11100011 =-(1100011) =-(64+32+8+4) =-99 となり、 元の数=-12 結果 =-99 で、結果が元の数×2^-2(=元の数×1/4)と結果が合いません。 先頭符号を空いたビットに移動した部分は数えないのでしょうか。 すると、 元の値 =-12 結果  =-3 で結果が合う気がします。 過去の回答や検索サイトなどで調べてみましたがピンときません。 テキストにも、10進数での数値表記はなく、 答え合わせができなくて困っております。 どなたかお答えいただけると助かります。 どこが間違っているのか混乱しております。 先頭ビットが正負の符号ビットという前提の例題なのですが、 マイナス符号がついている前提となるので 先頭ビットや空いたビットに入れた符号ビットも含めて 「2の補数」で考える必要があるのかどうかも よくわからなくなってきました。 つまり、元の数値「10001100」は「-12」ではなく -(01110100) =-(64+32+16+4) =-116 なのでしょうか なお、C言語は今のところ学習していないので、 C言語にまつわるご回答ですともっとわからなくなりそうです。 単純に間違いを指摘していただけると大変助かります。 よろしくお願いします。

  • 算術シフトしたら、あれ?

    16進数ので各4ビット(4桁)で2進数で算術シフトしますが、符号部はぬいて元の16進数に戻すのですか?でもそうすると元の数より大幅に減ってしまいますよね。例題の 例題・A4A6(16)を2ビット算術シフトする。 A4A6(16)=1010 0010 1010 0110 (2) ・左へ2ビットシフトする。 1000 1010 1001 1000(2)=A98(16) ・右へ2ビットシフトする。 1110 1000 1010 1001(2)=8A9(16) というように、符号部ぬかしたら増えるはずが減ったり、減るはずが増えたりと。なんか変ですよね。 ちなみに符号部すべて入れて考えたら、 左へ算術シフト 8A98(16) 右へ算術シフト E8A9(16) 増えるはずが減って、減るはずが増えるというあべこべになってしまいます。 超基本的ことなんですが、なぜか本に記載されていなかったので書きました。ご協力ください。

  • [2進数 シフト演算 除算について]

    [2進数 シフト演算 除算について] シフト演算について勉強中です。ご協力お願い出来たら幸いです。 乗算について例えば『1010』(符号ビットを考えず)を2倍 4倍 8倍(2のn乗)した場合 ビットを2倍であれば1つ、4倍であれば2つ・・・左に シフトすれば良いというのは理解しました。 また3倍 5倍などのケースも、 3倍であれば1ケタ左にシフトした数+1010で求まる事も理解しました。 問題は除算です。他の質問を探ってみたのですが、考え方は一緒という回答で・・・詰まっています 除算は右シフトとの事ですが 先ほどの例である『1010』(10)ですがこれを1/2、つまり2で割ると 1つ右にシフトし1010→0101 となり 1010を1/4する場合右に2ビットシフトし 1010→0010.10 となり理解は出来ます。 しかし1/3 、1/5といった場合の計算の仕方が分かりません。 余りを出さないという考えで(近似値になると思いますが) 解き方をご教授願えたらと思います。

  • 循環シフト。

    (ABCD)16 を右へ3ビットシフトした結果を16進数で表した場合の答えは BCDAだと間違っているのでしょうか? 循環シフトってはみ出た部分を前にもってくるのでこれであってるはずなのですが。

  • シフトレジスタのビットレートについて

    シフトレジスタ初心者です。 シフトレジスタにより1と0の信号を出力しようとしています。 現在考えているのは約10Mbit/s~20Mbit/sの出力を考えています。 (周波数で言えば10MHz~20MHz?まちがっているかもしれませんが。。) シフトレジスタはクロックを入力するようになっていますが、そのクロックの周波数を 10MHz~20MHzの周波数に設定すればよいのでしょうか? 詳しい方、教えてください。

  • ビット演算で00000001と1の頭に0を付ける?

    https://www.grapecity.com/japan/powernews/column/clang/019/page02.htm ビット演算子 表1にCのビット演算子を掲げておきます。ビット演算とは言っても、扱う値はバイト単位などCの一般的な整数のデータ型です。ビット演算子は、それらの値をビット単位で計算します。 ビットシフト演算(<< >>)~2倍と1/2 例えばunsigned char型の1は、2進数では"00000001"という形のビット列(ビットパターン)になります。これを1桁左にずらす(シフトする)と"00000010"となります。ずらしてあふれた左端の0は消え、空いた右端には0が入ります。 "00000001"は10進数の「1」、"00000010"は10進数の「2」です。つまり、ビット列を左に1桁シフトすると値は2倍になるのです。 -----------------------------------------  以上ですが、C言語の、ビット演算の解説の抜粋です。ビット演算はまだ覚えたてですが、"00000001"整数1の頭にわざわざ、0を沢山 つける目的は何なのでしょうか!?  よろしくお願いします。

  • C言語のビットシフトの質問

    C言語の右ビットシフトで、以下のプログラムの結果について、納得できずにいます。 dを右にシフトすると、上位ビットには0が入るのではないでしょうか? よろしくお願いします。 プログラム unsigned char d='0'; printf("%c\n", d); printf("%c\n", d>>5); 結果 0 『

専門家に質問してみよう