Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Java] Problem z BigInteger i BigDecimal

Ostatnio zmodyfikowano 2013-02-28 00:20
Autor Wiadomość
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ć?
P-77030
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.
P-77048
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.
P-77052
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
P-77091
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.
P-77155
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.
P-77157
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 ?
P-77159
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
P-77162
« 1 » 2
  Strona 1 z 2 Następna strona