バイト配列をその数値に変換する方法(Java)?


89

8バイトの配列があり、対応する数値に変換したいと思います。

例えば

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

上記の変換操作を実行するメソッドが必要です。


4
「数値」とはどういう意味ですか?バイトは2進数で整数(long)または浮動小数点数(double)を表しますか?それらは数値の文字列表現ですか?またはさらに別の表現?
starblue

1
これは参考になりました:stackoverflow.com/questions/5399798/...
TacB0sS

注意:TacB0sSのリンクは、私が実際に探していたものでした-前方および後方変換の両方。
ジェイテイラー

new BigInteger(by).longValue()
ローンの侯爵

回答:


106

最初のバイトが最下位バイトであると仮定します:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

最初のバイトが最も重要で、次に少し異なります:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

8バイトを超える場合は、longをBigIntegerに置き換えます。

私のエラーを修正してくれたAaron Digullaに感謝します。


8
-1バイトは符号付きの値です!そして、pow()をシフト(<<)に置き換えます!"値=(値<< 8)+(by [i]&0xff)"
アーロン・ディグラ

シフト演算子(<<)は右から左に優先されますか?上記のコードはどのように機能しますか?私にとっては問題なく動作しています。ちょうど働きを知りたいです。前もって
ありがとう

@Mnementh:シフト演算子(<<)は右から左に優先されますか?上記のコードはどのように機能しますか?私にとっては問題なく動作しています。ちょうど働きを知りたいです。前もって
ありがとう

5
他の誰かが同じ問題を抱えている場合、最初の例では、by [i]をlongにキャストする必要があります。それ以外の場合は、2 ^ 32未満の値に対してのみ機能します。つまり、value += ((long)by[i] & 0xffL) << (8 * i);
ルーク

115

パッケージのBuffer一部として提供されているを使用java.nioして、変換を実行できます。

ここで、ソースbyte[]配列の長さは8であり、これはlong値に対応するサイズです。

最初に、byte[]配列がでラップされ、ByteBuffer次にByteBuffer.getLongメソッドが呼び出されてlong値を取得します。

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

結果

4

ByteBuffer.getLongコメントでメソッドを指摘してくれたdfaに感謝します。


この状況では適用できない場合もありますが、Buffersの優れた点は、複数の値を持つ配列を見ることです。

たとえば、8バイトの配列があり、それを2つのint値として表示したい場合は、byte[]配列をにラップしてByteBuffer、として表示し、次IntBufferの方法で値を取得できますIntBuffer.get

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

結果:

1
4

ByteBuffer.wrap(new byte [] {0、0、0、1、0、0、0、4})。getLong()はどうですか?このメソッドは次の8バイトを読み取り、それらをlongに変換する必要があります
dfa

@dfa:指摘してくれてありがとう、きっとうまくいくようです-答えを編集します。:)
coobird

16

これが8バイトの数値の場合、次のことを試すことができます。

BigInteger n = new BigInteger(byteArray);

これがUTF-8文字バッファーの場合、次のことを試すことができます。

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));

最初のコードスニペットの直後に終了した場合、または文字列を「数値」に変換するコードが含まれている場合、私はこの回答に投票しました。現状のままでは、あなたの回答の後半は不平等ではないようです。
ローレンスゴンサルベス

そもそも私が言ったことではなく、私は私の答えを変更しました
ヴィンセント・ロバート


9

可変長バイトにBigIntegerを使用することもできます。必要に応じて、Long、Integer、Shortのいずれかに変換できます。

new BigInteger(bytes).intValue();

または極性を示すには:

new BigInteger(1, bytes).intValue();


1

配列内の各セルはunsigned intとして扱われます。

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}

私が0xFFLを使用する必要があったことに注意してください。そうでなければ、int 0xFFからlongへのキャストは、Long.toHexString(l)を出力したときに誤った1ビットがたくさん設定されていました。
ルーク

0xFFLを使用する必要があります。そうしないと、符号拡張が得られます。
グレー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.