Próbuję znaleźć skuteczny algorytm w Javie, aby znaleźć powtarzającą się część dziesiętną dwóch liczb całkowitych a
i b
gdzie a/b
.
na przykład. 5/7 = 0,714258 714258 ....
Obecnie znam tylko metodę długiego podziału.
algorithms
math
Jun Hao
źródło
źródło
Odpowiedzi:
Uważam, że istnieją tutaj dwa ogólne podejścia, możesz zasadniczo „brutalną siłą” szukać najdłuższego powtarzającego się łańcucha lub możesz rozwiązać go jako problem teorii liczb.
Dawno nie natknąłem się na ten problem, ale szczególny przypadek (1 / n) to problem nr 26 w Project Euler, więc możesz znaleźć więcej informacji, szukając skutecznych rozwiązań dla tej konkretnej nazwy. Jedno wyszukiwanie prowadzi nas do strony Eli Bendersky'ego, gdzie wyjaśnia swoje rozwiązanie . Oto niektóre teorie ze strony dziesiętnych rozszerzeń Mathworld :
Moja teoria liczb jest w tej chwili trochę zardzewiała, więc najlepsze, co mogę zrobić, to skierować cię w tym kierunku.
źródło
Pozwól
n < d
, a ty próbujesz wymyślić powtarzającą się częśćn/d
. Niechp
będzie liczbą cyfr w powtarzającej się części: wtedyn/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
. Część w nawiasach jest serią geometryczną równą1/(10^p - 1)
.Tak
n / d = R / (10^p - 1)
. Zmień kolejność, aby uzyskaćR = n * (10^p - 1) / d
. Aby znaleźć R, zapętlićp
od 1 do nieskończoności i zatrzymać, gdy tylkod
równomiernie się dzielin * (10^p - 1)
.Oto implementacja w Pythonie:
(
k
śledzi długość powtarzającej się sekwencji, dzięki czemu można na przykład odróżnić od 1/9 do 1/99)Zauważ, że ta implementacja (jak na ironię) zapętla się na zawsze, jeśli rozwinięcie dziesiętne jest skończone, ale kończy się, jeśli jest nieskończone! Możesz jednak sprawdzić ten przypadek, ponieważ
n/d
będzie miał skończoną reprezentację dziesiętną tylko wtedy, gdy wszystkie czynniki pierwsze,d
które nie są 2 lub 5, są również obecnen
.źródło
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
itd.Dzielenie liczb wielocyfrowych? : /
Zamień wynik w ciąg, a następnie zastosuj do niego ten algorytm . Użyj BigDecimal, jeśli ciąg nie jest wystarczająco długi dla zwykłych typów.
źródło