30 marca 2012

Konwersja o połowę podstawy

Bardzo miły sposób mnożenia, dzielenia występuje wtedy, kiedy oba wyrażenia zapiszemy przy podstawie mniejszego z nich. Jest to wtedy odpowiednik mnożenia przez '10'.

Kłopotliwy jest powrót do systemu początkowego. Ale wykorzystując równe liczby zapisane inaczej:
a_n p^n + ... + a_1 p + a_0 przy podstawie 2n
2^n a_n p^n + ... + 2 a_1 p + a_0 przy podstawie n
uzyskujemy kolejną, stosunkowo szybką metodę konwersji.

Przykładowo, liczba trójcyfrowa w systemie o podstawie 288 mająca następującą postać:
1.54.53
po konwersji do systemu o podstawie połowę mniejszej, 144 przyjmuje postać:
4.108.53
Przekształcenia: [1*4, 54*2(<144), 53] = [4, 108, 53]. Nie trzeba używać przeniesień, które występują, gdy iloczyn na miejscu cyfry będzie większy niż podstawa systemu.

Podobnie przy zwiększaniu podstawy systemu należy dzielić przez potęgi 2 w takiej potędze, jak daleko są one od cyfry najmniej znaczącej. Oczywiście cyfry po każdej zmianie systemu warto naprawiać.

Sposób ten oraz konwersje na sąsiedni system pozycyjny p -> p+1 opisane kilka postów wcześniej pozwalają błyskawicznie pomnożyć, i wrócić do systemu początkowego. Może to być wygodniejsze niż mnożenie pisemne.

Do pełnej implementacji pozostaje jeszcze sprowadzenie liczby do systemu, w którym będziemy mnożyć, dzielić. Możemy to zrobić w czasie O( log^2 ).
Jeśli chcemy zapisać liczbę a w systemie o podstawie b, najpierw wpuszczamy a między dwie sąsiednie potęgi
b^n < a < b^(n+1).
Następnie połowimy b zacieśniając przedział występowania b jak w wyszukiwaniu binarnym. Kiedy z b dojdziemy do 0, znajdziemy najbardziej znaczącą cyfrę a w systemie o podstawie b.
Zagęszczeń danej cyfry mamy tyle, jak długa jest liczba b. Powtarza się tyle razy, ile cyfr ma docelowa postać liczby a.