Nitr0Skay Temat założony przez niniejszego użytkownika |
[Java] Problem z BigInteger i BigDecimal » 2013-02-25 22:50:54 Witam, mam pewien problem. Bawiłem się trochę tym BigInteger i BigDecimal i w efekcie napisałem taki program: import java.math.BigInteger; import java.math.BigDecimal;
public class Lekcja6 { public static void main(String[] args) { BigInteger a = new BigInteger("9454657554456546546"); BigInteger b = new BigInteger("5562444564564686546"); BigInteger suma = a.add(b); BigInteger roznica = a.subtract(b); BigInteger mnozenie = a.multiply(b); BigInteger dzielenie = a.divide(b); System.out.println("Suma = " +suma.toString()); System.out.println("Różnica = " +roznica.toString()); System.out.println("Mnożenie = " +mnozenie.toString()); System.out.println("Dzielenie = " +dzielenie.toString()); BigDecimal c = new BigDecimal("466565884.4698797974"); BigDecimal d = new BigDecimal("854776185.6566546568"); BigDecimal suma2 = c.add(d); BigDecimal roznica2 = c.subtract(d); BigDecimal mnozenie2 = c.multiply(d); BigDecimal dzielenie2 = c.divide(d); System.out.println("Suma2 = " +suma2.toString()); System.out.println("Różnica2 = " +roznica2.toString()); System.out.println("Mnożenie2 = " +mnozenie2.toString()); System.out.println("Dzielenie2 = " +dzielenie2.toString()); } } Po Naciśnięciu Run, pierwsza część programu (Ta z BigInteger) działa poprawnie, tzn na konsoli pojawia się taki wynik: Suma = 15017102119021233092 Różnica = 3892212989891860000 Mnożenie = 52591008523607269227049550120148970116 Dzielenie = 1 Ale zaraz pod tym, konsola zwraca błąd (To w części z BigDecimal) następujący: Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(Unknown Source) at Lekcja6.main(Lekcja6.java:24) I w efekcie, cała treść konsoli po skompilowaniu programu wygląda tak: Suma = 15017102119021233092 Różnica = 3892212989891860000 Mnożenie = 52591008523607269227049550120148970116 Dzielenie = 1 Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(Unknown Source) at Lekcja6.main(Lekcja6.java:24) Moje pytanie brzmi następująco: Co może być powodem tego błędu i jak to mogę naprawić? |
|
DejaVu |
» 2013-02-25 23:59:36 Być może wynik obliczeń zapisujesz do typu, który nie jest w stanie pomieścić wyniku - stąd ten błąd. |
|
Nitr0Skay Temat założony przez niniejszego użytkownika |
» 2013-02-26 00:37:07 Raczej nie sądzę - Zapisuję to tak jak w przypadku BigInteger do obiektu typu BigDecimal. A klasy te (BigInteger i BigDecimal) są wstanie pomieścić niemal nieograniczenie wielkie liczby, dzięki temu, że są one konwertowane na łańcuchy znaków (przy pomocy .toString()) Po za tym, część z BigInteger zapisałem podobnie no i działa, zatem myślę, że błąd występuje gdzieś indziej. |
|
Chlorek |
» 2013-02-26 18:43:23 Po pierwsze wynik dzielenia wygląda na błędny i błąd tyczy się właśnie nie operacji na BigDecimal tylko na BigInteger podczas dzielenia. Nie jestem pewien ale możliwe, że podczas dzielenia liczba jest niewymierna i leci w ułamki bez końca. Spróbuj zaokrąglania wyników. Nie wiem, czy to jest to, ale rzuciło mi się w oczy.
#Edit Oh ja głupi. Przecież pisze, że 21 linia :D Czyli błąd z BIgDecimal podczas dzielenia, ale błąd tyczy się tego samego - zaokrąglij liczbę lub spróbuj dla testu 4 podzielić przez 2 :D |
|
Nitr0Skay Temat założony przez niniejszego użytkownika |
» 2013-02-26 21:43:12 BigDecimal c = new BigDecimal("4"); BigDecimal d = new BigDecimal("2"); BigDecimal suma2 = c.add(d); BigDecimal roznica2 = c.subtract(d); BigDecimal mnozenie2 = c.multiply(d); BigDecimal dzielenie2 = c.divide(d);
Suma2 = 6 Różnica2 = 2 Mnożenie2 = 8 Dzielenie2 = 2 Zauważyłem, że jak dzielę BigDecimal przez inną BigDecimal o wartości z przecinkami i przez niektóre liczby całkowite to zwraca powyższy błąd. Jednak przy niektórych liczbach całkowitych problem ten nie występuje. Ogólnie nie wiem, dlaczego. |
|
Chlorek |
» 2013-02-26 22:13:21 Spróbuj podzielić 10 na 3 i zobacz czy masz ten błąd. Jeśli tak to chodzi o to, że liczba (ułamek) nie ma skończonego rozwinięcia dziesiętnego. |
|
Nitr0Skay Temat założony przez niniejszego użytkownika |
» 2013-02-26 22:22:34 BigDecimal c = new BigDecimal("10"); BigDecimal d = new BigDecimal("3"); BigDecimal suma2 = c.add(d); BigDecimal roznica2 = c.subtract(d); BigDecimal mnozenie2 = c.multiply(d); BigDecimal dzielenie2 = c.divide(d);
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(Unknown Source) at Lekcja6.main(Lekcja6.java:24) Zatem, jak rozwiązać ten problem i dlaczego on w ogóle występuje ? |
|
Chlorek |
» 2013-02-26 22:38:21 Jak podzielisz liczbę 10 przez 3 to otrzymasz 3.33333333333... czyli 3.(3). Liczba nigdy się nie kończy. Użyj jakiejś funkcji zaokrąglającej. Na jakiejś stronce znalazłem taki kod, który zaokrągli wynik: BigDecimal dzielenie2 = c.divide(d, RoundingMode.HALF_UP);
Nie sprawdzałem, czy działa, gdyż nie chce mi się teraz nawet otwierać IDE :P |
|
« 1 » 2 |