お世話になります。
loと申します。よろしくお願いいたします。
ビットの操作が分からなくて、悩んでいます。
大変申し訳ないのですが、皆様の力をお貸しください。
下記のプログラムにて、
bufに格納されている、数値(No)を取り出し、
その数値(No)を書き換えたあと、
再度、bufに格納する。
というプログラムを書きたいのですが、
再度、bufに格納する操作が分かりません。
(逆の手順を踏めば良いことはわかるのですが。。。)
大変お手数ですが、やり方をお教え願えないでしょうか?
よろしくお願いいたします。
******************************************
unsigned char No;
unsigned long buf;
No = (unsigned char)( ( buf >> 14 ) & 0x07l );
// Noに任意の数値を格納する。
// bufに書き戻す。
******************************************
No = (任意の数値); // Noに任意の数値を格納する。
buf = (unsigned long)No; // bufに書き戻す。
訊きたいのはこういう事でなくて?
確信犯ですか?
http://www.mtakahashi.com/cgi.cgi?13303
> 2005 06/29 11:26
> マルチポストはいかんよ。
> http://www.vcppclub.com/bbs1/wforum.cgi?mode=allread&no=2387&page=0
tib様ご回答ありがとうございます。
bufのビット構成なのですが、下記のようになっております
1 2 3 ・・・13 14 15 16 17 18 19 20 21 ・・・
| Staion | No | Data
このbufより
Noのみを取り出し→No書き換え→bufに書き戻す
という処理を行いたいのです。
共用体(union)とか使ってみるとか。
Station、No、Data を取り出し、buf は 0 にして、No を書き換えて、& で
元に戻せばよいと思います。
>& で元に戻せばよいと思います。
訂正: | で元に戻せばよいと思います。
よくやるのは、書き換えたくない部分をONにしたマスクを作って
アンドをとってNoの部分をオフビットにしたデータを作成して
書き換えたNoをビットシフトして上のデータとオアを取る。
割とよくやるビット演算なので覚えておく方が良いかと。
同じような操作を何回もやるのであれば、関数化しておいた方が便利かな。
> 共用体(union)とか使ってみるとか。
union の書式に自信がない。。。
ビットフィールド使えばいいのかなと安直に考えたのでちょっとサンプル作ってみました。
でも動作確認はしていません。
'&'や'|'を使った演算の他にも、一応こんな手もありますよって事で。
struct bitData
{
unsigned Station : 14;
unsigned No : 3;
unsigned Data : 15;
};
union AAA
{
struct bitData data1;
unsigned long data2;
};
int main(void)
{
union AAA aaa ;
unsigned long buf;
aaa.data2 = buf ;
aaa.data1.No = 3 ; // Noに任意の数値を格納する。
buf = aaa.data2 ; // bufに書き戻す。
return 0;
}
ビットフィールドを使った時点で移植性は0ですけどね。
ビットフィールドのビットが具体的にどのように取られるかは処理系定義なので。
MSB 側からビットフィールドを使い始める処理系と
LSB 側からビットフィールドを使い始める処理系と、両方ありますので。
and/or/xor を使えば移植性は一応確保できます。
ちょっと違うけど、以前、unsigned char型変数の指定ビットをON/OFF(1/0)するマクロを組ん
でいました。
参考になるのでは?
// 指定ビットをONにする
#define MAKEONBIT( ucdata, bitNo ) ( (unsigned char)( (ucdata) |= ( 0x01 <<
(bitNo) ) ) )
// 指定ビットをOFFにする
#define MAKEOFFBIT( ucdata, bitNo ) ( (unsigned char)( (ucdata) &= ( ~( 0x01 <<
(bitNo) ) ) ) )
なぜか、マクロにしていましたが、関数化した方がいいかもしれませんね。
> ちょっと違うけど、以前、unsigned char型変数の指定ビットをON/OFF(1/0)するマクロを組
んでいました。
std::bitset なんてのもあるです。
std::bitset<16> bs;
bs.set(0); // bit-0を1に
bs.reset(1); // bit-1を0に
bs.flip(2); // bit-2を反転
unsigned long n = bs.to_ulong();
…などなど。