2011-01-22 9 views
21

私はファイルから読み込んだbyte[]を持っていて、その中の2バイトからintを得たいと思っています。ここでは例です:2バイトを整数に読み込みますか?

byte[] bytes = new byte[] {(byte)0x00, (byte)0x2F, (byte)0x01, (byte)0x10, (byte)0x6F}; 
int value = bytes.getInt(2,4); //This method doesn't exist 

これは0x0110、または小数で272valueを等しくする必要があります。しかし明らかに、byte[].getInt()は存在しません。どのように私はこの仕事を達成することができますか?

上記の配列は単なる例です。実際の値はわかりません。

+0

答えがうまくいかない理由は、バイトが整数に昇格されているためです。 "bytes [2] * 256"は1バイトに収まらないが、 "256"は整数などであるため問題にはならない。 – SyntaxT3rr0r

+1

[Convert 4 bytes to int]の重複可能性(http://stackoverflow.com/questions/2383265/convert-4-bytes-to-int) – finnw

答えて

36

あなただけのシンプルを選ぶ必要があります。

int val = ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff); 

あなたは計算があなたのコードをpepperingたくありませんでしたが、私はそれはおそらくだろうと思えばあなたも、あなたに機能性を与えるために、独自のヘルパー関数getBytesAsWord (byte[] bytes, int start)を書くことができ過度のものである。

+1

理想的には(b1 << 8)| (b2&0x00ff) 2番目のバイト値が128より大きい場合、javaはバイトを負のintとみなすため、上記の変換では誤った値が返されます。 – Gopi

+0

なぜ '0xff'ですか?言い換えれば、 'bytes [0] << 8の違いは何ですか?バイト[1] '? – arve0

+1

@ arve0参照:http://stackoverflow.com/a/11380077/1685098 –

1

また、あなたが使用できます。

int val = (bytes[2] << 8) + bytes[3] 
+1

いいえ:bytes [2]が0x7fより大きい場合、負のintを返します。 paxdiabloの答えからの "&0xff"が必要です。 – Francois

6

試してみてください。

public static int getInt(byte[] arr, int off) { 
    return arr[off]<<8 &0xFF00 | arr[off+1]&0xFF; 
} // end of getInt 

をあなたの質問は2つの引数(2,4)は何を意味するのかを示すものではありませんでした。 2と4はあなたの例では配列のインデックスとしてox01と0x10を見つけるためには意味がありません。私はあなたが共通の2つの要素を取りたいと思ったので、私のメソッドでは+ 1を使いました。

Javaでbyte []クラスを拡張することはできません。したがって、bytes.getIntメソッドを持つことはできません。したがって、最初のargとしてbyte []を使用する静的メソッドを作成しました。

このメソッドの「トリック」は、バイトが8ビットであることです。の0x80を超える整数と値は負で符号拡張されます(つまり、intとして使用すると0xFFFFFF80)。そのため、「& 0xFF」のマスキングが必要です。 '< < 8'は、上位8ビットを左にシフトします。 '|' '+'と同じように2つの値を組み合わせます。 < <の優先順位が最も高く、その後に&が続きますので、演算子の順序が重要です。 - かっこは必要ありません。

+0

Thxこの素晴らしい説明です。同じことだが署名値については、私が使った: 'return arr [off] << 8 | arr [off + 1] &0xFF; ' –

0

ByteBufferを使用できます。それはあなたが探しているgetIntメソッドと他の多くの便利なメソッドを持っています

2

ここでは、シンプルで信頼性の高い方法です。

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4); 
    // by choosing big endian, high order bytes must be put 
    // to the buffer before low order bytes 
    byteBuffer.order(ByteOrder.BIG_ENDIAN); 
    // since ints are 4 bytes (32 bit), you need to put all 4, so put 0 
    // for the high order bytes 
    byteBuffer.put((byte)0x00); 
    byteBuffer.put((byte)0x00); 
    byteBuffer.put((byte)0x01); 
    byteBuffer.put((byte)0x10); 
    byteBuffer.flip(); 
    int result = byteBuffer.getInt(); 
0

Google Base16クラスはGuava-14.0.1です。

new BigInteger(com.google.common.io.BaseEncoding.base16().encode(bytesParam),16).longValue(); 
関連する問題