ビットデータの格納

[戻る]
出直し三平 2003/02/13(木) 14:45:32
こんにちは、以下a,b,c,dをd[2]に取得したいのですが、
方法がわかりません。

どなたか宜しくお願います。


  ビット数  ビット列表記
a   1       左ビットが先頭であるビット列    
b   1       左ビットが先頭であるビット列    
c   2       左ビットが先頭であるビット列    
d  12       最上位ビットが先頭、符号無し整数

a = 1,b = 0,c = 11は固定値

--------------------------------------

char d[2];

--------------------------------------

2003/02/13(木) 14:57:01
d[2] 内に a,b,c,d をどう割り付けたいのか何も規定していない以上どなたにも
説明は出来ないと思います

:      d[0]     :      d[1]     :
 F E D C B A 9 8 7 6 5 4 3 2 1 0
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|a|b| c |          c            |


のように出来れば図示して説明してください

出直し三平 2003/02/13(木) 15:54:37
>>d[2] 内に a,b,c,d をどう割り付けたいのか何も規定していない以上どなたにも
>>説明は出来ないと思います

:      d[0]     :      d[1]     :
 F E D C B A 9 8 7 6 5 4 3 2 1 0
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|a|b| c |          c            |



すみません。島さんのおっしゃる通りです。
宜しくお願いします。

2003/02/13(木) 15:58:47
変数か定数か分りませんが a,b,c,d の型が良く判らない上に、その型内でのビット位置が
又不明な事にお気づきでしょうか?

出直し三平 2003/02/13(木) 16:10:57
:      d[0]     :      d[1]     :
 F E D C B A 9 8 7 6 5 4 3 2 1 0
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|a|b| c |          d            |

またまた、すみません。
a,b,cはともにビット固定値です。

dは12ビットの可変値です。

他に不明な点はありますか?

2003/02/13(木) 16:26:13
C/C++ では整数の仲間と考えられるのは
char, unsigned char, short, unsigned short, long, unsigned long
(他に long long や _int64 なんていうのがある場合もある)ですが、
1ビットだけの型や2ビットだけの型は使う人が定義しないと存在できないと思います
ですから a,b,c,d の定義や宣言を示して下さいと言っているのです
例えば d について最上位ビットが先頭、符号無し整数と規定していますが

!76543210!76543210!
|******** ****|        (1)
    |**** ********|    (2)

型が short の場合について考えてみますが、(1),(2) の二通りの割り付け方があった時に
あなたはどちらの割り付け方を指しているのかが私には何もわからないということです

アイススケーター 2003/02/13(木) 16:29:09
各データの重みをつけて掛け算して、その合計を求め(USHORT)
上位8ビットと下位8ビットに分けるでは・・・

Green 2003/02/13(木) 16:48:12
こんな感じでどうでしょうか?
ちなみにIRIXで確認していて(2)の形になっています。
Windowsの場合ちょっと工夫しなければなりません。


>!76543210!76543210!
>|******** ****|        (1)
>    |**** ********|    (2)


#include <stdio.h>

union {
        struct {
                char   a:1;
                char   b:1;
                char   c:2;
                short  d:12;
        } d1;
        char   d2[2];
} data

int main(int argc, char * argv[])
{
        data.d1.a = 1;
        data.d1.b = 0;
        data.d1.c = 3;
        data.d1.d = 1;

        return 0;
}

~

tib 2003/02/13(木) 16:56:01
a, b, c, dという4つのデータをなんとかして2バイトに収めたい、ということなら
bitfieldで各データを宣言して、要素数2のchar配列と共用体に入れてしまってはどうで
しょう。

typedef union
{
    struct
    {
        unsigned short a:1;
        unsigned short b:1;
        unsigned short c:2;
        unsigned short d:12;
    }    bit;
    char d[2];
} hogehoge_t;

こんな型を作っておけば、

    hogehoge_t    hoge;
    hoge.bit.a    =    1;    // 固定値
    hoge.bit.b    =    0;    // 固定値
    hoge.bit.c    =    3;    // 固定値
    hoge.bit.d    =    (任意の数値) & 0x0fff;
    // ↑安全のため12bitでマスクしておく

というように使えますし、

    memcpy( &(hoge.d[0]), 0, sizeof(hogehoge_t) );
→
というように使えます。もちろん、

    sizeof(hogehoge_t) → 2

になります。

になります。...こう書いてみるとchar変数との共用体にする必要がないようにも思いま
す。(むしろunsigned shortの変数との共用体の方が使いでがありそう)hoge.dにアクセス
する必要がないのなら上記の構造体だけをtypedefして使うだけでいいでしょう。

a, b, c, dがそれぞれどこのbitに割り当てられるのかについて厳密にコントロールしな
くてはならない場合(各bitのフォーマットが既に決まっていてそれに従わなくてはならな
い場合)は、構造体の宣言順を変える必要があるかも知れませんので確認してください。
一般的にビットフィールドへのアクセスは普通の変数にアクセスするよりも手間がかかる
分、遅くなります。とにかく高速さが求められる、というプログラムにはお勧めできません。

REE 2003/02/13(木) 17:12:48
凝らずにこれでいいんじゃないでしょうか?

d[0] = 0xb0 | ((D >> 8) & 0x0f); // 0xb=1(a) 0(b) 11(c) 
d[1] = D & 0xff;

出直し三平 2003/02/13(木) 18:23:26
[[解決]]
REEさんの言う通りです。
私の説明不足です。すみません。

みなさん、有難うございました。

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