Bagaimana cara mengonversi array byte menjadi nilai numeriknya (Java)?


89

Saya memiliki array 8 byte dan saya ingin mengubahnya menjadi nilai numerik yang sesuai.

misalnya

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

// CONVERSION OPERATION
// return the numeric value

Saya menginginkan metode yang akan melakukan operasi konversi di atas.


4
Apa yang Anda maksud dengan "nilai numerik"? Apakah byte mewakili bilangan bulat (panjang) atau bilangan titik mengambang (ganda) dalam biner? Apakah mereka representasi string dari sebuah angka? Atau representasi lain?
starblue


NB: Tautan TacB0sS adalah apa yang sebenarnya saya cari - baik ke depan maupun ke belakang.
Jay Taylor

new BigInteger(by).longValue()
Marquis dari Lorne

Jawaban:


106

Dengan asumsi byte pertama adalah byte paling signifikan:

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

Apakah byte pertama yang paling signifikan, kemudian sedikit berbeda:

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

Ganti long dengan BigInteger , jika Anda memiliki lebih dari 8 byte.

Terima kasih kepada Aaron Digulla atas koreksi kesalahan saya.


8
-1 byte adalah nilai yang ditandatangani! Dan ganti pow () dengan shift (<<)! "value = (value << 8) + (oleh [i] & 0xff)"
Aaron Digulla

Apakah operator shift (<<) memiliki hak ke kiri? Bagaimana cara kerja kode di atas? Semuanya bekerja dengan baik untukku. Hanya ingin tahu cara kerjanya. Thanx in advance
suraj

@Mnementh: Apakah operator shift (<<) memiliki prioritas dari kanan ke kiri? Bagaimana cara kerja kode di atas? Semuanya bekerja dengan baik untukku. Hanya ingin tahu cara kerjanya. Thanx in advance
suraj

5
Jika ada orang lain yang memiliki masalah yang sama dengan yang saya lakukan, pada contoh pertama, by [i] harus dilemparkan ke long, jika tidak, ini hanya berfungsi untuk nilai yang kurang dari 2 ^ 32. Yaitu,value += ((long)by[i] & 0xffL) << (8 * i);
Lukas

115

Seseorang dapat menggunakan Buffers yang disediakan sebagai bagian dari java.niopaket untuk melakukan konversi.

Di sini, byte[]larik sumber memiliki panjang 8, yang merupakan ukuran yang sesuai dengan suatu longnilai.

Pertama, byte[]array dibungkus dalam a ByteBuffer, dan kemudian ByteBuffer.getLongmetode dipanggil untuk mendapatkan longnilai:

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

System.out.println(l);

Hasil

4

Saya ingin berterima kasih kepada dfa karena menunjukkan ByteBuffer.getLongmetode ini di komentar.


Meskipun mungkin tidak dapat diterapkan dalam situasi ini, keindahan Bufferdatang dengan melihat array dengan banyak nilai.

Misalnya, jika kita memiliki array 8 byte, dan kita ingin melihatnya sebagai dua intnilai, kita bisa membungkus byte[]array dalam ByteBuffer, yang dipandang sebagai a IntBufferdan mendapatkan nilainya dengan 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);

Hasil:

1
4

bagaimana dengan ByteBuffer.wrap (byte baru [] {0, 0, 0, 1, 0, 0, 0, 4}). getLong ()? metode ini harus membaca 8 byte berikutnya dan mengubahnya menjadi long
dfa

@ dfa: Terima kasih telah menunjukkannya, sepertinya berhasil - Saya akan mengedit jawabannya. :)
coobird

16

Jika ini adalah nilai numerik 8 byte, Anda dapat mencoba:

BigInteger n = new BigInteger(byteArray);

Jika ini adalah buffer karakter UTF-8, maka Anda dapat mencoba:

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

Saya akan memilih jawaban ini jika itu berakhir tepat setelah potongan kode pertama, atau jika itu menyertakan beberapa kode untuk mengubah string menjadi "nilai numerik". Apa adanya, paruh kedua dari jawaban Anda tampak seperti non sequitur.
Laurence Gonsalves

Bukan apa yang saya maksudkan sejak awal, saya mengubah jawaban saya
Vincent Robert


9

Anda juga dapat menggunakan BigInteger untuk byte dengan panjang variabel. Anda dapat mengubahnya menjadi Long, Integer atau Short, mana saja yang sesuai dengan kebutuhan Anda.

new BigInteger(bytes).intValue();

atau untuk menunjukkan polaritas:

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


1

Setiap sel dalam larik diperlakukan sebagai 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;
}

Hanya catatan bahwa saya perlu menggunakan 0xFFL, jika tidak, cast dari int 0xFF ke long memiliki banyak set 1 bit yang salah ketika saya mencetak Long.toHexString (l).
Luke

Anda perlu menggunakan 0xFFL jika tidak Anda mendapatkan ekstensi tanda.
Gray
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.