Liczba nie mieszcząca się w 32 bitach.

0

Potrzebuję napisać program na symulator PC-SPIM procesora MIPS R2000 który liczy funkcję silnia.
Problem polega na tym, że obliczenia szybko rosną i wynik nie mieści się w rejestrze 32 bitowym a tylko takie posiada ten cały MIPS.

W procesorze MIPS gdy wynik mnożenia jest tak duży, że nie mieści się do rejestru 32 bitowego to część wyniku leci do drugiego rejestru i niby wszystko jest w porządku.

Jednak ja potrzebuję na tym wyniku, który jest w dwóch rejestrach wykonać kolejne mnożenia. Instrukcja przy której pomocy mnożę pobiera tylko jeden rejestr więc nie wiem jak liczyć na dwóch rejestrach.

Czy istnieje jakiś algorytm (lub instrukcja o której nie wiem) który pozwala liczyć na dwóch oddzielnych rejestrach i traktuje je jak jedna liczbę?

1

Czy ty sobie zdajesz sprawę z tego jak szybko silnia rośnie? Nawet na 64 bitach zmieścisz ledwo 20!. Jesteś pewien że potrzebujesz trzymać takie duże liczby? Bo ja zgaduje że masz jakiś symbol newtona albo jakiś szereg i wcale nie musisz nigdzie liczyć takich dużych silni...

1

Z twojego opisu wynika, że mnożenie na MIPS odbywa się dokładnie tak samo jak na x86-32 - tam też rejestry są co najwyżej 32-bitowe (pomijając SIMDy i FPU), a wynik mnożenia dwóch 32-bitowych rejestrów jest umieszczany w parze rejestrów EAX:EDX (oba 32-bitowe).

A więc poszukaj ogólnych algorytmów do mnożenia bignumów, to że robisz to na MIPS nie ma wielkiego znaczenia.

1

zgadzam się z @Shalom, najpierw napisz co ty właściwie robisz, a nie na czym utkwiłeś. Poza tym w jakim języku to piszesz (asembler)?
Co do wielkich liczb to można robić obliczenia na tak dużych liczbach na ile wystarczy pamięci. Najprostszy algorytm opiera się o zwykłe pisemnym mnożeniu, którego uczą w podstawówce (jeden rejestr to odpowiednik jednej cyfry).

0

Zgadza się mam do policzenia takie rzeczy jak wariacje, kombinacje. We wzorze jest silnia i właśnie do tego jest mi potrzebna.
Program mam napisać w asemblerze procesora MIPS R2000. Jeśli ktoś jest ciekawy to tu może zobaczyć mniej więcej jak to wygląda
http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm
Wiem że w niektórych przypadkach mogę skrócić silnię z licznika z silnią z mianownika ale i tak mam nadal bardzo duże liczby.
Właśnie dlatego napisałem bo źle to wygląda gdy już przy 13! mój program podaje zły wynik.

0

Pisanie mnożenia i dzielenia wielkich liczb w asemblerze to dość dużo pracy. W google spokojnie znajdziesz przykłady w większości języków, ale jeśli sobie przypomnisz pisanie i dzielnie pisemne z podstawki to powinieneś w stanie to zrobić bez pomocy z internetu.
Jeśli się możesz podeprzeć bibliotekami to skorzystaj z gmplib.

0

@Papec ja myśle że jednak jak masz symbol newtona to zawsze możesz sobie skrócić licznik i mianownik i spokojnie możesz liczyć nawet dla sporych danych. Nawet jeśli zaimplementujesz sobie mnożenie pisemne to będzie się to koszmarnie ślimaczyć.

0

Niestety z silnią to tak łatwo chyba w ASM nie będzie, tutaj przykład dla x86 (stosuje bignumy):

http://digitalpbk.blogspot.com/2008/11/masm-assembly-factorial-program-big.html

0
Papec napisał(a):

Wiem że w niektórych przypadkach mogę skrócić silnię z licznika z silnią z mianownika ale i tak mam nadal bardzo duże liczby.

Jeżeli skrócenie licznika z mianownikiem Ci nie wystarcza, to chyba musisz sobie przypomnieć własności działań na logarytmach i funkcję Γ. Sporo informacji jest na Wikipedii. Możesz też znaleźć przykład implementacji w "Numerical Recipes in C", i przełożyć to jakoś na potrzebny Ci język.

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