2009-06-22 14 views
78

Mam tablicę 8-bajtową i chcę przekonwertować ją na odpowiadającą jej wartość liczbową.Jak przekonwertować tablicę bajtów na jej wartość liczbową (Java)?

np.

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

// CONVERSION OPERATION 
// return the numeric value 

Chcę metodę, która wykona powyższą operację konwersji.

+4

Co masz na myśli przez "wartości liczbowej"? Czy bajty reprezentują liczbę całkowitą (długą) lub zmiennoprzecinkową (podwójną) w systemie binarnym? Czy są one ciągiem reprezentującym liczbę? A może kolejna reprezentacja? – starblue

+1

To było pomocne: http://stackoverflow.com/questions/5399798/byte-array-and-intversion-in-java – TacB0sS

+0

Uwaga: Połączenie TacB0sS było tym, czego szukałem - zarówno konwersjami do przodu, jak i do tyłu. –

Odpowiedz

92

Zakładając, że pierwszy bajt jest najmniej znaczący bajt:

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

Czy pierwszy bajt najbardziej znaczący, to jest trochę inna:

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

Wymień długo z BigInteger, jeśli masz więcej niż 8 bajtów.

Podziękowania dla Aarona Digulla za korektę moich błędów.

+6

-1 bajty są wartościami podpisanymi! I zastąp pow() z przesunięciem (<<)! "value = (value << 8) + (przez [i] & 0xff)" –

+0

Masz rację. Naprawiłem to, mam nadzieję, że teraz jest poprawne. – Mnementh

+0

Czy operator przesunięcia (<<) ma pierwszeństwo od prawej do lewej? Jak działa powyższy kod? Wszystko działa dobrze dla mnie. Po prostu chcę poznać pracę. Z góry z wyprzedzeniem – suraj

101

Można użyć Buffer s dostarczonych jako część pakietu java.nio do przeprowadzenia konwersji.

W tym przypadku tablica źródłowa byte[] ma długość 8, która jest wielkością odpowiadającą wartości long.

Pierwsza tablica byte[] zapakowane jest w ByteBuffer, a następnie metoda ByteBuffer.getLong jest powołany do uzyskania wartości long:

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

System.out.println(l); 

Wynik

4 

Chciałbym podziękować DFA do wskazywania metody ByteBuffer.getLong w komentarzach.


Mimo, że nie może mieć zastosowania w tej sytuacji, piękno Buffer y wyposażone patrząc na tablicę z wielu wartości.

Na przykład, jeżeli miała tablicy 8 bajtów, i chce go zobaczyć w dwóch int wartości, to może owijać tablicę byte[] w sposób ByteBuffer, który jest postrzegany jako IntBuffer oraz uzyskania wartości, 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); 

Wynik:

1 
4 
+0

+1 dla tablicy z wieloma wartościami – dfa

+0

co z ByteBuffer.wrap (nowy bajt [] {0, 0, 0, 1, 0, 0, 0, 4}). GetLong()? ta metoda powinna przeczytać następny 8 bajtów i przekonwertować je na długi kod: – dfa

+0

@dfa: Dzięki za wskazanie, że na pewno działa - będę edytować odpowiedź. :) – coobird

15

Jeśli jest to 8-bajtów wartość numeryczna, można spróbować:

BigInteger n = new BigInteger(byteArray); 

Jeśli jest to bufor znaków UTF-8, to można spróbować:

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

Głosowałbym na tę odpowiedź, jeśli zakończyłoby się tuż po pierwszym fragmencie kodu lub zawierało jakiś kod do przekonwertowania ciągu znaków na "wartość numeryczną". Tak jak jest, druga połowa twojej odpowiedzi wydaje się być non sequitur. –

+0

Nie to, co miałem na myśli, zmieniłem moją odpowiedź: –

12

Wystarczy, można użyć lub odnoszą się do guawa lib ceł dedowane przez google, który oferuje użyteczne metody konwersji między tablicą długą a bajtową. Mój kod klienta:

long content = 212000607777l; 
    byte[] numberByte = Longs.toByteArray(content); 
    logger.info(Longs.fromByteArray(numberByte)); 
+0

https://google.github.io/guava/releases/21.0/api/docs/com/google/common/primitives/Longs.html –

7

Można również użyć BigInteger dla zmiennych długości bajtów. Możesz przekonwertować go na Długi, Integer lub Krótki, w zależności od Twoich potrzeb.

new BigInteger(bytes).intValue(); 

lub do określenia polaryzacji:

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

Każda komórka w tablicy jest traktowany jako 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; 
} 
+0

Po prostu notatka że potrzebowałem użyć 0xFFL, w przeciwnym razie rzutowanie z int 0xFF na long miał dużo niepoprawnych 1 bitów ustawionych podczas drukowania Long.toHexString (l). – Luke

Powiązane problemy