• ベストアンサー

ビット演算について

いつもお世話になります。 ビット演算について教えて下さい。 unsigned char buf1[1]=0x5a unsigned char buf1[2]=0x04 unsigned char buf1[3]=0x38 5a0438(16)を3バイトの値を12ビットずつの整数で得るにはどうしたらいいのでしょうか? 2進数表記では、 5A | 04 | 38 01011010 | 00000100 | 00111000 12ビットずつとは、 010110100000 010000111000 と区分し、10進数の整数値で得たいです。どのようにすればよいでしょうか? また、0x5Aなどの16進数を2進数のビットで考えるときに、 01011010を下位4ビットを10進数整数を得るにはどうしたらよいのでしょうか? 上記2点、どうぞよろしくお願い致します。

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

論理演算とビットシフトの組み合わせてで実現できます。 とその前に、10進数整数を得ると書かれてますがコンピュータの整数値は基本的に2進数で内部処理されます。 10進数は表示時にprintf関数がワザワザ10進数に変換しているのであって、内部では2進数な事を忘れないでください。 intもshortもcharも全て2進数(binary)です。 >unsigned char buf1[1]=0x5a >unsigned char buf1[2]=0x04 >unsigned char buf1[3]=0x38 short uppper12bit = (buf[1] << 4) | (buf[2] >> 4); short under12bit = ((buf[2]&0x0f)<<8) | buf[3]; printf("上12bit=%d 下12bit=%d\n",uppper12bit,under12bit); >また、0x5Aなどの16進数を2進数のビットで考えるときに、01011010を下位4ビットを10進数整数を得るにはどうしたらよいのでしょうか? unsigned char under4bit = buf[1] & 0x0f; printf("上4bit=%d\n",under4bit); 16進数も2進数と書き方が違うだけで同じものです。これといった複雑なことが行われているわけではありません。C言語は16進数で代用できるので2進数が言語上存在しないのです。

the-ai
質問者

お礼

丁寧な回答ありがとうございます。 大変助かりました。 ビット演算をもう少し勉強します。 本当に有難うございました。

その他の回答 (2)

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.3

php504 さんの回答で気になったのは、格上げがあるのでキャストの必要がないだろうという点と、シフトとビットアンドの優先度の違いですね^^; the-ai さんの質問で気になったのは、添え字は 0 からにしたほうが自然だろうという点と、バイト順を意識してほんとにしたいことをしているのか、という点です^^ ちょっとした老婆心ですが(笑)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

単に3バイト(24ビット)を12ビットに分けるだけなら (unsigned short)buf[1] << 4 | buf[2] >> 4; buf[1]を4ビット左へシフトして空いた4ビット分にbuf[2]を右に4ビットシフトした値を入れる (unsigned short)buf[2] & 0x0F << 8 | buf[3]; buf[2]の下位4ビットを左に8ビットシフトして空いた8ビットにbuf[3]を入れる 下位4ビットだけにしたいなら 0x5A & 0x0F;

the-ai
質問者

お礼

早速の回答ありがとうございます。 助かりました。 ビットシフト/演算をもう少し勉強します。 有難うございました。