2013-02-17 14 views
11

Dlaczego ten kod rzucić NumberFormatException:Java, Long.parse binarnego String

String binStr = "1000000000000000000000000000000000000000000000000000000000000000"; 
System.out.println(binStr.length());// = 64 
System.out.println(Long.parseLong(binStr, 2)); 
+2

Ponowne przeczytanie tego, to właściwie dobre pytanie. –

+6

+1 Dobre pytanie. –

+1

To może być * interesujące * pytanie, ale z pewnością nie jest to [* dobre * pytanie] (http://meta.stackexchange.com/questions/156810/stack-overflow-question-checklist). – Jeroen

Odpowiedz

7

1000000000000000000000000000000000000000000000000000000000000000 jest większa niż Long.MAX_VALUE.

Zobacz https://stackoverflow.com/a/8888969/597657

Rozważ użycie BigInteger(String val, int radix) zamiast.


EDIT:

OK, to jest dla mnie nowe. Wygląda na to, że analizowanie binarne jako wielkości znaku nie jest dopełnieniem 2-s-go.

+0

Tęskniłeś za tym, co przegapiłem, kiedy po raz pierwszy skomentowałem;) Nie jest * większy * ... nie istnieje. –

+0

'String binStr =" 1000000000000000000000000000000000000000000000000000000000000000 "; System.out.println (binStr.length()); // = 64 System.out.println (Long.parseLong (binStr, 2)); ' –

+1

Łączna odpowiedź jest błędna, Java reprezentuje liczby całkowite jako uzupełnienie 2-s wewnętrznie, a nie wielkość znaku. –

5

Ponieważ jest poza zakresem. 1000...000 jest 2 , ale Long idzie tylko do 2 - 1.

+0

Tęskniłeś za tym, co przegapiłem, kiedy po raz pierwszy skomentowałem;) Nie jest * większy *, nie istnieje. –

+0

Po całej naszej dyskusji, * powinien * być 'Long.MIN_VALUE' od wzoru bitowego, ale' parseLong' to nie podoba. Naucz się czegoś nowego każdego dnia :) –

2

Największy długo wartość jest rzeczywiście:

0111111111111111111111111111111111111111111111111111111111111111b = 9223372036854775807 
3

ta jest taka sama dla wszystkich Long, Integer, a ShortByte. Wytłumaczę z Byte przykład dlatego, że jest czytelny:

System.out.println(Byte.MIN_VALUE); // -128 
System.out.println(Byte.MAX_VALUE); // 127 
String positive = "1000000"; // 8 binary digits, +128 
String negative = "-1000000"; // 8 binary digits, -128 
String plus  = "+1000000"; // 8 binary digits, +128 
Byte.parseByte(positive, 2); //will fail because it's bigger than Byte.MAX_VALUE 
Byte.parseByte(negative, 2); //won't fail. It will return Byte.MIN_VALUE 
Byte.parseByte(plus, 2);  //will fail because its bigger than Byte.MAX_VALUE 

Cyfry interpretowane są niepodpisane, bez względu na to, co jest podstawa. Jeśli chcesz uzyskać wartość ujemną, musisz mieć znak minus na początku ciągu. JavaDoc mówi:

Przetwarza argument ciąg jako podpisał długo w radix określonym przez drugi argument. Wszystkie znaki w łańcuchu muszą być cyframi określonej podstawki (co określa, czy Character.digit(char, int) zwraca wartość nieujemną), z tym wyjątkiem, że pierwszy znak może być być znakiem minus ASCII '-' ('\u002D'), aby wskazać wartość ujemną lub znak ASCII plus '+' ('\u002B'), aby wskazać wartość dodatnią. Wygenerowana długa wartość jest zwracana.

W celu uzyskania MAX_VALUE musimy:

String max = "1111111"; // 7 binary digits, +127 
// or 
String max2 = "+1111111"; // 7 binary digits, +127 
1

To dlatego Long.parseLong nie można analizować dwójkowego reprezentacji dopełniacza. Jedynym sposobem, aby zanalizować uzupełnienie dwójkowe reprezentację ciąg binarny w Java SE jest BigInteger:

long l = new BigInteger("1000000000000000000000000000000000000000000000000000000000000000", 2).longValue() 

Daje spodziewać -9223372036854775808result

0

Jest to największy możliwy długi (9223372036854775807 = 2 exp 63 - 1) w formacie binarnym . Zwróć uwagę na L na końcu ostatniej cyfry.

long largestLong = 0B0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L;