2

説明できない奇妙なことを発見しました。ここの誰かが、これが何であるか、またはなぜ起こっているのかを見ることができるなら、私は知りたい. 私がやっていることは、次のように高く整列された 12 ビットを含む unsigned short を取得することです。

1111 1111 1111 0000

次に、短いバイトの各バイトが MSB をパッドとして 7 ビットを保持するようにビットをシフトします。上記の結果は次のようになります。

0111 1111 0111 1100

私がやったことはこれです:

unsigned short buf = 0xfff;
//align high
buf <<= 4;

buf >>= 1;
*((char*)&buf) >>= 1;

これにより、正しいように見えますが、最後のシフトの結果は次のように設定されたビットのままになります。

0111 1111 1111 1100

非常に奇妙な。unsigned char を一時ストレージとシフトとして使用すると、次のように機能します。

unsigned short buf = 0xfff;
buf <<= 4;

buf >>= 1;
tmp = *((char*)&buf);
*((char*)&buf) = tmp >> 1;

この結果は次のとおりです。

0111 1111 0111 1100

ここで何が起こっているのですか?

4

2 に答える 2

4

はい、charプラットフォームで署名されているようです。もしそうなら*((unsigned char*)&buf) >>= 1、それはうまくいくでしょう。

于 2010-05-16T18:08:09.663 に答える
1

これを分解しましょう。あなたのコンパイラは short を 16 ビットのメモリと考えていると仮定します。

unsigned short buf = 0xfff; 
//align high 
buf <<= 4; 

次と同等です。

unsigned short buf = 0xfff0;

... と

buf >>= 1; 

buf の値は 0x7ff8 になります (つまり、th ビットが 1 ビット右にシフトされます)。今あなたの派手なラインのために:

*((char*)&buf) >>= 1; 

ここで多くのことが起こっています...最初に左側を解決する必要があります。あなたが言っているのは、 buf を取り、それを8ビットのメモリへのポインタとして扱うことです(それは自然な16ビットではありません)。buf が最初に参照した 2 バイトは、メモリのエンディアンが何であるかを知ることに依存しています (ビッグ エンディアンの buf が 0x7f を指している場合、リトルエンディアンの buf が 0xf8 を指している場合)。Intel ボックス (リトルエンディアン) を使用していると仮定します。現在、buff は 0xf8 を指しています。次に、ステートメントは、そのバイトに割り当て、そのバイトの値を1つ右にシフトした(およびcharが署名されているため、符号が拡張された)、または0xfcと述べています。他のバイトは変更されません。符号拡張が必要な​​い場合は、chast buf を (unsigned char *) にします。

于 2010-05-16T18:10:55.773 に答える