2015-07-01 24 views
78

Testowałem warunki brzegowe na pewnym kodzie obejmującym BigDecimal i zauważyłem, że kiedy BigDecimal jest inicjowany za pomocą String "1e2147483647", zachowuje się nieoczekiwanie. Wydaje się mieć wartość między 0 i 1e-2147483647. Kiedy próbuję zadzwonić pod numer intValue(), otrzymuję numer NegativeArraySizeException. Powinienem zauważyć, że 2147483647 jest maksymalną wartością liczby całkowitej w moim systemie. Czy robię coś nie tak, czy jest to problem z BigDecimal?Możliwy błąd przepełnienia Java BigDecimal

BigDecimal test = new BigDecimal("1e2147483647"); 

test.compareTo(new BigDecimal(0)); //Returns 1 
test.compareTo(new BigDecimal("1e-2147483647")); //Returns -1 
test.intValue(); //Throws NegativeArraySizeException 
+0

http://stackoverflow.com/questions/17945985/what-are-the-limits-of-bigdecimal-and-biginteger – kosa

+0

Dzięki, nie widziałem tego pytania. Byłem po prostu zaskoczony, że nie rzucił wyjątku NumberFormatException z konstruktora, tak jak robi to dla cyfry o jeden cyfrę większej. – DJMatch3000

+0

Jest to raczej sugestia niż wiedza, ale '1e-2147483647' jest dość dużą liczbą. Mówiąc dokładniej, 'log_2 (10^2147483647)/8/1024^3 = 0.83 ...' powinien dawać minimalny rozmiar (w gigabajtach) reprezentujący tak dużą liczbę jako liczbę całkowitą. Może to jakiś problem z alokacją pamięci? – Turing85

Odpowiedz

87

Nie, wydaje się, że masz poważny błąd. Błąd występuje w JDK7, ale został naprawiony w JDK8. Twoje wartości są poprawnie reprezentowane jako BigDecimal s, i powinny zachowywać się poprawnie, ale nie.

Śledzenie przez the source code of BigDecimal, na linii 2585, this.precision() jest 1, a this.scale jest -2147483647. this.precision() - this.scale dlatego przepełnienia i następujące przepełnienie nie jest obsługiwane poprawnie.

Ten błąd has been fixed w JDK8 przez doing the subtraction in long arithmetic.

+0

Czy to w Javie Androida 17 (podobne do JDK6)? –

Powiązane problemy