Javaでvalue&0xffは何をしますか?


98

次のJavaコードがあります。

byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;

印刷すると結果は254になりますが、このコードがどのように機能するかはわかりません。&演算子が単にビット単位である場合、結果としてバイトではなく整数になるのはなぜですか?


コードをEclipseにコピーします。「タイプの不一致:intからbyteに変換できません」という警告が表示されます。int値= 0xfeに変更する必要があります。
ベン・チェン

1
@BenChengはする必要がありますbyte value = (byte) 0xfe;
BEK

回答:


171

の最下位8ビットにのresult8ビットを配置valueした結果の(符号なし)値に設定されますresult

このようなものが必要なのはbyte、Javaの署名付き型だからです。あなたが書いたばかりなら:

int result = value;

その後、result最終的にのff ff ff fe代わりに値になり00 00 00 feます。さらに微妙なのは、&int1でのみ動作するように定義されているため、次のようになります。

  1. valueintff ff ff fe)に昇格します。
  2. 0xffあるintリテラル(00 00 00 ff)。
  3. &以下のための所望の値を得るために適用されますresult

(ポイントへの変換でint起こる前に、&オペレータが適用されます。)

1 まあ、結構です。&オペレータは、上で動作longのいずれかのオペランドがある場合は、同様の値long。しかし、ではありませんbyte。Java言語仕様のセクション15.22.1および5.6.2を参照してください。


その表記でxはどういう意味ですか?xは数値または16進数ではありませんか?
Callat

3
@KazRodgers- 0x(または0X)接頭辞は、後続の整数リテラルを16進数(16進数)として解釈する必要があることをJavaに伝えます。Javaは、08進リテラルのベアプレフィックスとバイナリリテラルの0b(または0B)プレフィックスもサポートします。整数リテラルの詳細については、Java言語仕様を参照してください。
Ted Hopp、2016

次のリテラル?たとえば、0x3faがあった場合。3faはリテラル番号に変換される部分であり、0xは「これは16進数です」と注記していますか?@TedHopp?
Callat

1
@KazRodgers-その通りです。なお、0xまたは0b単独で(以下のいずれかの数字せず)は、Javaで不正な構文です。
Ted Hopp、2016

1
@DmitryMinkovsky- fe8ビットの2の補数の16進ビットパターンは、10進数の値-2に対応します。値を保持するにInteger.valueOf(byte)ff ff ff fe00 00 00 fe(10進数の値254)ではなく、(32ビットで−2、2の補数)を生成する必要があります。この変換(byte値からfeintff ff ff fe)として知られている符号拡張と、Java言語仕様の一部です。の目的はvalue & 0xff、符号拡張を元に戻すことです(つまり、ゼロ拡張をシミュレートするために、Javaにはありません)。
テッドホップ2018

57

http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xffから

16進リテラル0xFFは、等しいint(255)です。Javaはintを32ビットとして表します。バイナリでは次のようになります。

00000000 00000000 00000000 11111111

任意の数値に対してこの値(255)でビットごとのANDを実行すると、数値の最下位8ビットを除いてすべてマスクされます(ゼロになります)(そのままになります)。

... 01100100 00000101 & ...00000000 11111111 = 00000000 00000101

&は%に似ていますが、実際にそうではありませ

そして、なぜ0xffなのか?これは((2の累乗)-1)です。すべての((2の累乗)-1)(たとえば、7、255 ...)は、%演算子のように動作します。

次に
、バイナリでは、0はすべてゼロ、255は次のようになります。

00000000 00000000 00000000 11111111

そして、-1はこのように見えます

11111111 11111111 11111111 11111111

0xFFと0から255までの値のビットごとのANDを実行すると、結果は値とまったく同じになります。また、255より大きい値を入力しても、結果は0〜255の範囲になります。

ただし、次の場合:

-1 & 0xFF

あなたは得る

00000000 00000000 00000000 11111111、元の値-1(1111111110進数で255)と等しくありません。


いくつかのビット操作:(質問とは関係ありません)

X >> 1 = X/2
X << 1 = 2X

特定のビットが設定されている(1)か、設定されていない(0)かを確認します。

 int thirdBitTobeChecked =   1 << 2   (...0000100)
 int onWhichThisHasTobeTested = 5     (.......101)

 int isBitSet = onWhichThisHasTobeTested  & thirdBitTobeChecked;
 if(isBitSet > 0) {
  //Third Bit is set to 1 
 } 

特定のビットを設定(1)

 int thirdBitTobeSet =   1 << 2    (...0000100)
 int onWhichThisHasTobeSet = 2     (.......010)
 onWhichThisHasTobeSet |= thirdBitTobeSet;

特定のビットをReSet(0)

int thirdBitTobeReSet =   ~(1 << 2)  ; //(...1111011)
int onWhichThisHasTobeReSet = 6      ;//(.....000110)
onWhichThisHasTobeReSet &= thirdBitTobeReSet;

XOR

XOR演算を2回実行すると、結果は同じ値になることに注意してください。

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

byte encryptedVal  =  toBeEncrypted ^ salt == 0110 1101
byte decryptedVal  =  encryptedVal  ^ salt == 0010 0110 == toBeEncrypted :)

XORのもう1つのロジックは

if     A (XOR) B == C (salt)
then   C (XOR) B == A
       C (XOR) A == B

上記は、以下のように一時なしで2つの変数を交換するのに役立ちます

a = a ^ b; b = a ^ b; a = a ^ b;

または

a ^= b ^= a ^= b;



4

それは多くのコードを減らすのに役立ちます。8ビットで構成されるRGB値で時々使用されます。

0xFFでは意味する 24(0)および8(1'S)など00000000 00000000 00000000 11111111

変数を効果的にマスクして、最後の8ビットの値のみを残し、残りのビットをすべて無視します

これは、カラー値を特別な形式から標準のRGB値(8ビット長)に変換しようとする場合などによく見られます。

素晴らしい説明はこちら


0

32ビット形式のシステムでは、16進数値は10進数であることを0xff表します。また、ビットごとの&演算子は、最初のオペランドと同じ右端の8ビットをマスクします。00000000000000000000000011111111255(15*16^1+15*16^0)


もう少し説明してもらえますか?
ashishdhiman2007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.