ビット操作について

[戻る]
lo 2005/06/29(水) 11:33:18
お世話になります。
loと申します。よろしくお願いいたします。
ビットの操作が分からなくて、悩んでいます。
大変申し訳ないのですが、皆様の力をお貸しください。

下記のプログラムにて、
bufに格納されている、数値(No)を取り出し、
その数値(No)を書き換えたあと、
再度、bufに格納する。
というプログラムを書きたいのですが、
再度、bufに格納する操作が分かりません。
(逆の手順を踏めば良いことはわかるのですが。。。)
大変お手数ですが、やり方をお教え願えないでしょうか?
よろしくお願いいたします。

*********************************************
unsigned char    No;
unsigned long    buf;
No = (unsigned char)( ( buf >> 14 ) & 0x07l );
// Noに任意の数値を格納する。
//  bufに書き戻す。
*********************************************

tib 2005/06/29(水) 11:42:03
No = (任意の数値);        // Noに任意の数値を格納する。
buf = (unsigned long)No;  //  bufに書き戻す。

訊きたいのはこういう事でなくて?

dark 2005/06/29(水) 11:43:00
確信犯ですか?

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

lo 2005/06/29(水) 11:57:01
tib様ご回答ありがとうございます。

bufのビット構成なのですが、下記のようになっております

1  2  3   ・・・13 14 15 16 17 18 19 20 21 ・・・
|     Staion       |   No   |     Data   

このbufより
Noのみを取り出し→No書き換え→bufに書き戻す
という処理を行いたいのです。

dark 2005/06/29(水) 12:11:24
共用体(union)とか使ってみるとか。

まきじ [E-Mail] 2005/06/29(水) 13:01:51
Station、No、Data を取り出し、buf は 0 にして、No を書き換えて、& で
元に戻せばよいと思います。

まきじ [E-Mail] 2005/06/29(水) 13:14:00
>& で元に戻せばよいと思います。

訂正: | で元に戻せばよいと思います。

PATIO 2005/06/29(水) 13:23:15
よくやるのは、書き換えたくない部分をONにしたマスクを作って
アンドをとってNoの部分をオフビットにしたデータを作成して
書き換えたNoをビットシフトして上のデータとオアを取る。
割とよくやるビット演算なので覚えておく方が良いかと。
同じような操作を何回もやるのであれば、関数化しておいた方が便利かな。

2005/06/29(水) 14:52:19
> 共用体(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;
}

tetrapod 2005/06/29(水) 15:52:33
ビットフィールドを使った時点で移植性は0ですけどね。
ビットフィールドのビットが具体的にどのように取られるかは処理系定義なので。
MSB 側からビットフィールドを使い始める処理系と
LSB 側からビットフィールドを使い始める処理系と、両方ありますので。

and/or/xor を使えば移植性は一応確保できます。

KING・王 2005/06/30(木) 07:56:24
ちょっと違うけど、以前、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) ) ) ) )


なぜか、マクロにしていましたが、関数化した方がいいかもしれませんね。

επιστημη 2005/07/01(金) 11:37:50
> ちょっと違うけど、以前、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();

…などなど。

古いスレッドには追加発言できません。