4

8 ビット バイトでのみアドレス指定可能なデータ ストリームがあり、それを 6 ビット要素に解析し、それを配列に格納したいと考えています。これを行うための最もよく知られている方法はありますか?

11110000 10101010 11001100 

の中へ

のような配列

111100|001010|101011|001100

(パディングをゼロにすることができます。この方法でアドレス指定できる必要があります)

データは8ビット配列であり、これも6ビットの倍数であり、実際には無限ではありません

4

6 に答える 6

8

1 バイトのビット数は、特定のアーキテクチャによって異なります。6ビットアーキテクチャでは、それは非常に簡単です:-)

1 バイトあたり 8 ビットのアーキテクチャを想定すると、次のように何かを行う必要があります。

int sixbits(unsigned char* datastream, unsigned int n) {
    int bitpos = n*6;
    return (datastream[bitpos/8] >> bitpos%8)    // lower part of the five bit group
        + (datastream[bitpos/8+1] << 8-bitpos%8) // if bitpos%8>2, we need to add some carry bits from the next char
        & 0x3f;                                  // and finally mask the lowest 6 bits
}

ここで、n は n 番目の 6 ビット グループです。適切なコンパイラは、除算をシフトに、剰余を AND に置き換えます。この関数をループで使用して、目的の配列を埋めてください。

于 2009-12-08T22:25:49.550 に答える
1

5ビットシーケンスをカウントし、各バイトを読み取り、カウンターと予想されるワード位置に基づいてビットをシフトし(隣接するバイトワードからの排他的論理和によって)、正しく整列された新しいバイトワードを形成して処理します。

私はあなたがコードを期待しないことを願っています...

于 2009-12-08T22:23:33.187 に答える
1

ビットフィドルを使用してそれを行うことができます:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    unsigned char source[3] = { 15, 85, 51 };
    unsigned char destination[4];
    memset(destination, 0, 4);
    for (int i = 0; i < (8 * 3); ++i)
    {
        destination[i / 6] |= ((source[i / 8] >> (i % 8) & 1) << (i % 6));
    }

    for (int j = 0; j < 4; ++j)
        printf("%d ", destination[j]);
}

出力:

15 20 53 12

これは最下位5ビットから機能し始めることに注意してください。

      15       85       51
11110000 10101010 11001100
111100 001010 101011 001100
    15     20     53     12

最も重要なものを最初に取得するには、代わりに次のようにします。

destination[i / 6] |= ((source[i / 8] >> (7 - (i % 8))) & 1) << (5 - (i % 6));

これは、最上位ビットを最初に書いたと仮定して、例のように機能します。

240      170      204
11110000 10101010 11001100
111100 001010 101011 001100
60     10     43     12
于 2009-12-08T22:29:26.763 に答える
0

この連合はどうですか?

union _EIGHT_TO_SIX_ {

    struct {

       unsigned char by6Bit0 : 6;
       unsigned char by6Bit1 : 6;
       unsigned char by6Bit2 : 6;
       unsigned char by6Bit3 : 6;

    } x6;

    struct {

       unsigned char by8Bit0;
       unsigned char by8Bit0;
       unsigned char by8Bit0;

    } x8;
}

by8Bitxを設定すると、by6Bitxが自動的に入力されます~~~

于 2009-12-09T00:02:51.000 に答える
0

BitStreamの使用を検討します。一度に1ビットずつ読み取ることができます。そのビットを直接所定の位置にシフトできます(<< nを使用)。一度に8ビットバイトを読み取るほどのパフォーマンスは得られない可能性がありますが、見た目がよりきれいなコードになることは確かです。

于 2009-12-08T22:56:34.693 に答える
0

次のような構造体を使用するのはどうですか。

struct bit5
{
    unsigned int v1 : 5;
    unsigned int v2 : 5;
    unsigned int v3 : 5;
    unsigned int v4 : 5;
    unsigned int v5 : 5;
    unsigned int v6 : 5;
    unsigned int v7 : 5;
    unsigned int v8 : 5;
}; 

次に、バイト配列をstruct bit58 バイトごと (40 ビット = 5 ビットの 8 グループ、8 バイトに収まる) にキャストして、5 ビットのチャンクを取得します。言う:

unsigned char* array; // a byte array that you want to convert
int i;
struct bit5* pBit5;

for(i = 0; i < (int)(SIZE_OF_ARRAY / 8); i++)
    pBit5 = (struct bit5*)((int)array + i * 8);
于 2009-12-08T22:28:18.437 に答える