Przekroczenie zakresu typu double

Odpowiedz Nowy wątek
2014-12-20 17:17
0

Witam!
Nie jestem pewien czy nazwa tematu jest odpowiednia, ale tak czy tak opiszę mój problem.

Mianowicie...

Rzecz w tym, że mam napisać program do liczenia kilku zagadnień matematycznych takich jak silnia i tak dalej. Weźmy tą silnię pod młotek. Licząc małe silnie, rzędu do 18! to wszystko gra. Problem pojawia się, gdy chce obliczyć 19! i więcej. Wtedy mój program kończy działanie(każde od 19! do x!) wynikiem 92233720368547760. Jak sprawić, żeby program prawidłowo liczył wyższe silnie? Pomoże ktoś? Nie chcę się tutaj "chwalić" kodem. Powiem tylko, że działam na typie double, bo tak mi zostało zlecone zadanie. BigDecimal czy BigInteger nie wchodzi w grę. Da się w ogóle coś takiego wykonać czy zostałem wpuszczony w maliny?

Pozostało 580 znaków

2014-12-20 17:21

Jak sprawić, żeby program prawidłowo liczył wyższe silnie? Pomoże ktoś? Nie chcę się tutaj "chwalić" kodem.

Najpierw wyślij szklaną kulę. Względnie możesz po prostu napisać program poprawnie.

Z wikipedii:
max double = 1.7976931348623157 × 10^308

Spokojnie możesz policzyć np silnię ze stu. Tyle, że wynik będzie przybliżony.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2014-12-20 17:28
0

Silnie liczę metodą rekurencyjną:

static public double Silnia(double ekran)
    {
        if (ekran == 0) 
            return 1;
        else 
            return ekran * Silnia(ekran - 1);
    }

Funkcję wywołuję z parametrem double i wtedy pakuję w okienko:
this.jTextField1.setText((String.valueOf(df.format(wynik))));

Wiem, może niezbyt profesjonalne. Bawiłem sie DecimalFormat, stąd tam df.format.

Pozostało 580 znaków

2014-12-20 17:33
1

A zmienna wynik jaki ma typ? Zamień to setText(whatever) na setText(String.valueOf(wynik)) gdzie wynik ma typ double i nie ma żadnych konwersji na longi czy cokolwiek po drodze.

PS:
Z ciekawości wyguglałem liczbę która podałeś i znalazłem to: http://stackoverflow.com/ques[...]va-numeric-types-to-as3-types

PS2:
Parametr do silni powinien być typu int.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 3x, ostatnio: Wibowit, 2014-12-20 17:37

Pozostało 580 znaków

2014-12-20 17:39
0

Korzystając z typu long dojedziesz do 20!, a korzystając z typu double dojedziesz do 21!. Dalsze wartości są już przybliżone.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2014-12-20 17:49
0

Zamień to setText(whatever) na setText(String.valueOf(wynik)) gdzie wynik ma typ double i nie ma żadnych konwersji na longi czy cokolwiek po drodze.

Miałem tak na początku, to nawet 12! zapisywało w notacji wykładniczej, a tego nie potrzebuję.
Zmiana na int też nie pomogła w niczym.

Pozostało 580 znaków

2014-12-20 18:00
1

A wynik w notacji wykładniczej był prawidłowy?

Jeszcze 15 postów i dowiemy się w którym miejscu jest błąd :]

Jaki jest typ zmiennej wynik? Jest gdzieś rzutowanie na longa (implicite lub explicite)? Jak wygląda ten decimalformat?

Zamiana parametru na int nie ma pomóc tylko ma sprawić że kod będzie mniej WTFowy. Silnię oblicza się z argumentu będącego liczbą naturalną, a nie rzeczywistą.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2014-12-20 18:01

Pozostało 580 znaków

2014-12-20 18:06
0

Dobra. wynik jest typu double. Wynik w postaci wykładniczej był ten sam tyle że po pierwszej dziewiątce miałem kropeczkę i na końcu Ex, gdzie x to liczba w zależności od wielkości silni. DF wygląda tak:

DecimalFormat df = new DecimalFormat("#");

A, i może jeszcze istotny fakt(może). Dane pobieram z TextFielda, przez parsowanie do double. Później żeby zapisać wynik w TextFieldzie, parsuję wynik do Stringa

edytowany 1x, ostatnio: parawanada, 2014-12-20 18:08

Pozostało 580 znaków

2014-12-20 18:06
0
DecimalFormat df = new DecimalFormat("#############################################################################");
setText(df.format(wynik));

Hashy może być trochę mniej.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2014-12-20 18:09
0

Nie pomogło :<

Pozostało 580 znaków

2014-12-20 18:17
0

Gdzieś coś pokopałeś z zamianą typów bo twoja silnia działa.

http://ideone.com/T33feD
Wiki podaje 100! = 9.332621544×10^157
Program wypluwa 9.33262154439441E157 czyli 9.33262154439441 * 10^157

Wynik który otrzymujesz można wygenerować tym programem: http://ideone.com/Iolywr
Ale równie dobrze można też w taki sposób: http://ideone.com/RUXPnA
I wydaje mi się, że w twoim programie robisz tę drugą rzecz (co jest oczywistym błędem).

DecimalFormat dobrze też sobie radzi z dużym double: http://ideone.com/pjk3jz


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2014-12-20 18:22

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0