2017-03-29 21 views
1

私は次の方法があります:メソッドの0b1111_1111のバイト単位のビット単位の演算は何をしますか?

int convert3ByteChunkTo24Bits(final byte[] bytes) { 
    int bitsFor3ByteChunk = 0; 

    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[0] & 0b11111111); 

    bitsFor3ByteChunk = bitsFor3ByteChunk << 8; 
    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[1] & 0b11111111); 

    bitsFor3ByteChunk = bitsFor3ByteChunk << 8; 
    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[2] & 0b11111111); 

    return bitsFor3ByteChunk & 0b00000000_11111111_11111111_11111111; 
} 

目的は、渡されたバイトを追加し、int型の形式でそれを返すことです。ここで私が持っている試験方法である:結果の

void testConvert3ByteChunkTo24Bits() { 
    final byte ca = (byte) 0xCA; 
    final byte fe = (byte) 0xFE; 
    final byte ba = (byte) 0xBA; 

    final byte[] man = {ca, fe, ba}; 
    final int bytesIn24Bits = base64EncoderHelper.convert3ByteChunkTo24Bits(man); 

    System.out.println(bytesIn24Bits); 
} 

出力は次のようになります。

00000000110010101111111010111010 

これは正しいです、以来、意図した結果である:バイナリである

13303482 

0xCA = 11001010 
0xFE = 11111110 
0xBA = 10111010 

これまでのところ良い。

int convert3ByteChunkTo24Bits(final byte[] bytes) { 
    int bitsFor3ByteChunk = 0; 

    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[0]); 

    bitsFor3ByteChunk = bitsFor3ByteChunk << 8; 
    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[1]); 

    bitsFor3ByteChunk = bitsFor3ByteChunk << 8; 
    bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[2]); 

    return bitsFor3ByteChunk & 0b00000000_11111111_11111111_11111111; 
} 
:私は理解していないだけで一つのこと、次のように実装があるので、もし私は、ビット単位-と操作をしない場合は、なぜ私は

(bytes[0] & 0b11111111) 

のように論理的な論理積が必要なのでしょうがあります

結果は以下のようになります。

00000000111111111111111110111010 

私は何をしないのですか?何が

bytes[0] & 0b11111111 

ここに修正? (私は試行錯誤のようなものを見つけましたが、なぜそれは動作するのですか?)

+0

標識拡張?値0xFFのバイトをとり、intに格納して何を得るかを観察します。 –

+0

@ Jean-BaptisteYunèsの署名延長はどのような時点でですか? –

+0

バイト変数は式でintに変換されるため、符号拡張されます。 –

答えて

1

bitsFor3ByteChunk = bitsFor3ByteChunk | (bytes[0] & 0b11111111); 

bytes[0]最初int値(整数はすべての2の補数で表現される)に拡張されます。次にbyteに格納されている0xFFの値の場合、対応するintの値は0xFFFFFFFFになります。その後、下位8ビットを保持するためにマスクされます。

1

符号付きバイトを処理します。

たとえば、byte[0]の値は0b10000000です。それはあなたと私の128に似ていますが、two's complement arithmaticのためにJavaには-128のように見えます。その値をint型の計算で使用すると、数値がのintに符号拡張されます。値は-128です。

このコードでは、問題を回避するために、ビットごとに0b11111111と入力します。これは、整数演算であるので、バイトは暗黙的にint型11111111111111111111111110000000にキャストされていますが、andこれはnot having unsigned typesの悪名高いJavaの問題のためのハックです128

望まれる、00000000000000000000000010000000に変換します。で

0

人間が読める同等のは、単純に

Byte.toUnsignedInt(b) 

またはあなたが本当に明示的しかし非効率的にそれをしたい場合は次のとおりです。

b < 0? b + 256: b 

正直なところ、JDKの方法や簡単な計算を行うために存在する場合、そのようなコードを書きます同じことが難読化されているので、そのようなコードを書いている人が他の人とチームで結ばれないことを願っています... Cやその他の本質的に低レベルのバイトウォーリングでデバイスドライバを書いていない限りそのようなプロジェクト。

関連する問題