プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になります。
ビット演算について教えて下さい。

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点、どうぞよろしくお願い致します。

A 回答 (3件)

論理演算とビットシフトの組み合わせてで実現できます。



とその前に、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進数が言語上存在しないのです。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/09/06 11:20

php504 さんの回答で気になったのは、格上げがあるのでキャストの必要がないだろうという点と、シフトとビットアンドの優先度の違いですね^^;



the-ai さんの質問で気になったのは、添え字は 0 からにしたほうが自然だろうという点と、バイト順を意識してほんとにしたいことをしているのか、という点です^^ ちょっとした老婆心ですが(笑)
    • good
    • 0

単に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;
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/09/06 11:18

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