web-dev-qa-db-ja.com

AND 0xFFは何をしますか?

次のコードでは:

short = ((byte2 << 8) | (byte1 & 0xFF))

&0xFFの目的は何ですか?他のときとして私はそれが次のように書かれているのを見ます:

short = ((byte2 << 8) | byte1)

そしてそれもうまくいくようですか?

40
Muis

0xFFで整数をアンディングすると、最下位バイトのみが残ります。たとえば、short sの最初のバイトを取得するには、s & 0xFFと書くことができます。これは通常、「マスキング」と呼ばれます。 byte1がシングルバイトタイプ(uint8_tなど)であるか、すでに256未満である場合(その結果、最下位バイトを除くすべてゼロである場合)、上位バイトをマスクする必要はありません。それらは既にゼロであるため、ビット。

見る トリストピア署名付きのタイプを使用する場合の、以下のPatrickSchlüterの回答。ビット演算を行うときは、符号なしの型のみで作業することをお勧めします。

34
John Colanduoni

if byte1は8ビット整数型であり、それは無意味です-8ビットを超える場合、基本的に値の最後の8ビットを提供します。

    0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
 &  0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
    -------------------------------
    0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
27
D Stanley

byte1のタイプがcharの場合、2番目の式の危険性が生じます。その場合、一部の実装ではsigned charを使用でき、評価時に符号拡張になります。

signed char byte1 = 0x80;
signed char byte2 = 0x10;

unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));
unsigned short value2 = ((byte2 << 8) | byte1);

printf("value1=%hu %hx\n", value1, value1);
printf("value2=%hu %hx\n", value2, value2);

印刷します

value1=4224 1080     right
value2=65408 ff80    wrong!!

Solaris SPARC 64ビットのgcc v3.4.6で試しましたが、結果はbyte1およびbyte2charとして宣言されている場合と同じです。

TL; DR

マスキングは、暗黙的な符号拡張を回避することです。

[〜#〜] edit [〜#〜]:チェックしました。C++でも同じ動作です。

21

byte1がバイト(8ビット)であると仮定すると、バイトと0xFFのビット単位のANDを実行すると、同じバイトが取得されます。

byte1byte1 & 0xFFと同じです

byte101001101の場合、byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1と言う

Byte1が4バイトの整数のような他のタイプの場合、0xFFとのビット単位のANDにより、byte1の最下位バイト(8ビット)が残ります。

6
sr01853

byte1 & 0xffは、byte1の8つの最下位ビットのみがゼロ以外になることを保証します。

byte1がすでに8ビットのみの符号なし型である場合(例:char、またはほとんどの場合unsigned char)、違いはありません/完全に不要です。

byte1が符号付きまたは8ビットを超える型(たとえば、shortintlong)、および8以外のビットの場合最下位が設定されている場合、違いがあります(つまり、他の変数でoringの前にそれらの上位ビットがゼロになるため、orのこのオペランドは8つの最下位のみに影響します結果のビット)。

3
Jerry Coffin

最初のバイトにないすべてのビットをクリアします

1
thumbmunkeys

& 0xFF自体は、バイトが(言語標準で許可されている)8ビットより長い場合にのみ、残りが無視されることを保証します。

そしてそれもうまくいくようですか?

結果がSHRT_MAXを超えると、未定義の動作が発生します。その点で、両方とも同様に不十分に機能します。

0
Alexey Frunze