edit: (Я оставляю пост здесь для потомков. Но , пожалуйста больше не высказывайте это: это может быть теоретически полезно, но не очень практично. Я разместил другой ответ, который гораздо более полезен с практической точки зрения, не требует факторинга и не требует использования bignums.)
@ Думаю, у Даниэля Брукнера правильный подход. (требуется несколько дополнительных поворотов)
Возможно, есть более простой метод, но всегда будет работать следующий:
Давайте воспользуемся примерами q = x / y = 33/57820 и 44/65 в дополнение к 33/59, по причинам, которые вскоре могут стать понятными.
Шаг 1: множитель знаменателя (в частности, множители 2 и 5)
Напишите q = x / y = x / (2 a 2 5 a 5 z). Факторы 2 и 5 в знаменателе не приводят к повторным десятичным знакам. Таким образом, оставшийся коэффициент z взаимно прост с 10. Фактически, следующий шаг требует факторинга z, так что вы могли бы также сгенерировать все целое.
Рассчитайте 10 = макс. ( 2 , 5 ), который является наименьшим показателем 10, кратным коэффициентам 2 и 5 лет.
В нашем примере 57820 = 2 * 2 * 5 * 7 * 7 * 59, поэтому 2 = 2, 5 = 1, 10 = 2, z = 7 * 7 * 59 = 2891.
В нашем примере 33/59 59 - это простое число, не содержащее множителей 2 или 5, поэтому 2 = a 5 = a 10 = 0.
В нашем примере 44/65, 65 = 5 * 13 и a 2 = 0, a 5 = a 10 = 1.
Просто для справки я нашел хороший онлайн-калькулятор факторинга здесь . (даже делает totients, что важно для следующего шага)
Шаг 2: Используйте Теорема Эйлера или Теорема Кармайкла .
Нам нужно число n, такое, что 10 n - 1 делится на z или, другими словами, 10 n & эквивалент; 1 мод з. Функция Эйлера & phi; (z) и функция Кармайкла & lambda; (z) предоставят вам действительные значения для n, причем & lambda; (z) даст вам меньшее число, а & phi; (z), возможно, будет немного легче вычислить. Это не слишком сложно, это просто означает, что нужно учесть z и немного посчитать.
(2891) = 7 * 6 * 58 = 2436
& lambda; (2891) = 1 см (7 * 6, 58) = 1218
Это означает, что 10 2436 & экв .; 10 1218 & экв .; 1 (мод 2891).
Для более простой фракции 33/59: (59) = & lambda; (59) = 58, поэтому 10 58 и эквивалент; 1 (мод 59).
Для 44/65 = 44 / (5 * 13), & phi; (13) = & lambda; (13) = 12.
Ну и что? Ну, период повторяющейся десятичной дроби должен делить и & phi; (z), и & lambda; (z), чтобы они эффективно давали вам верхние границы периода повторяющейся десятичной дроби.
Шаг 3: Хруст номера
Давайте использовать n = & lambda; (z). Если мы вычтем Q '= 10 a 10 x / y из Q' '= 10 (a 10 + n) x / у, мы получаем:
m = 10 a 10 (10 n - 1) х / у
, которое является целым числом , потому что 10 a 10 кратно коэффициентам 2 и 5 y и 10 n -1 кратно оставшимся коэффициентам y.
То, что мы сделали здесь, это сместим влево исходное число q на 10 мест, чтобы получить Q ', и сместим влево q на 10 + n мест, чтобы получить Q '', которые повторяют десятичные дроби, но разница между ними - целое число, которое мы можем вычислить.
Тогда мы можем переписать x / y как m / 10 a 10 / (10 n - 1).
Рассмотрим пример q = 44/65 = 44 / (5 * 13)
a 10 = 1 и & lambda; (13) = 12, поэтому Q '= 10 1 q и Q' '= 10 12 + 1 д.
m = Q '' - Q '= (10 12 - 1) * 10 1 * (44/65) = 153846153846 * 44 = 6769230769224
, поэтому q = 6769230769224/10 / (10 12 - 1).
Другие фракции 33/57820 и 33/59 приводят к более крупным фракциям.
Шаг 4: Найти неповторяющиеся и повторяющиеся десятичные части.
Обратите внимание, что для k между 1 и 9 k / 9 = 0.kkkkkkkkkkkkk ...
Аналогично обратите внимание, что двузначное число kl от 1 до 99, k / 99 = 0.klklklklklkl ...
Это обобщает: для k-разрядных шаблонов abc ... ij это число abc ... ij / (10 k -1) = 0.abc ... ijabc ... ijabc. ..ij ...
Если вы следуете шаблону, вы увидите, что нам нужно взять это (потенциально) огромное целое число m, которое мы получили на предыдущем шаге, и записать его как m = s * (10 n -1) + r, где 1 & le; r <10 <sup>n -1.
Это приводит к окончательному ответу:
- s является неповторяющейся частью
- r является повторяющейся частью (дополняется нулями слева, если необходимо убедиться, что это n цифр)
- с 10 =
0, десятичная точка находится между
неповторяющаяся и повторяющаяся часть; если
a 10 > 0, то он расположен
10 мест слева от
соединение между s и r.
Для 44/65 получаем 6769230769224 = 6 * (10 12 -1) + 769230769230
s = 6, r = 769230769230 и 44/65 = 0,6769230769230, где подчеркивание здесь обозначает повторяющуюся часть.
Вы можете уменьшить числа, найдя наименьшее значение n на шаге 2, начав с функции Кармайкла & lambda; (z) и выяснив, приводит ли какой-либо из ее факторов к значениям n, таким, что 10 n & экв .; 1 (мод z).
обновление: Любопытно, что интерпретатор Python кажется самым простым способом вычисления с помощью bignums. (pow (x, y) вычисляет x y , а // и% - целочисленное деление и остаток соответственно.) Вот пример:
>>> N = pow(10,12)-1
>>> m = N*pow(10,1)*44//65
>>> m
6769230769224
>>> r=m%N
>>> r
769230769230
>>> s=m//N
>>> s
6
>>> 44/65
0.67692307692307696
>>> N = pow(10,58)-1
>>> m=N*33//59
>>> m
5593220338983050847457627118644067796610169491525423728813
>>> r=m%N
>>> r
5593220338983050847457627118644067796610169491525423728813
>>> s=m//N
>>> s
0
>>> 33/59
0.55932203389830504
>>> N = pow(10,1218)-1
>>> m = N*pow(10,2)*33//57820
>>> m
57073676928398478035281909373919059149083362158422691110342442061570390868211691
45624351435489450017295053614666205465236942234520927014873746108612936700103770
32168799723279142165340712556208924247665167762020062262193012798339674852992044
27533725354548599100657212037357315807679003804911795226565202352127291594603943
27222414389484607402282947077135939121411276374956762365963334486336907644413697
68246281563472846765824974057419578000691802144586648218609477689380837080594949
84434451746800415081286751988931165686613628502248356969906606710480802490487720
51193358699411968177101349014181943964026288481494292632307160152196471809062608
09408509166378415773088896575579384296091317883085437564856451054998270494638533
37945347630577654790729851262538913870632998962296783120027672085783465928744379
10757523348322379799377378069872016603251470079557246627464545140089934278796264
26841923209961950882047734347976478727084053960567277758561051539259771705292286
40608785887236250432376340366655136630923555863023175371843652715323417502594258
04219993081978554133517813905223106191629194050501556554825319958491871324801106
88343133863714977516430300933932895191975095122794880664130058803182289865098581
80560359737115185
>>> r=m%N
>>> r
57073676928398478035281909373919059149083362158422691110342442061570390868211691
45624351435489450017295053614666205465236942234520927014873746108612936700103770
32168799723279142165340712556208924247665167762020062262193012798339674852992044
27533725354548599100657212037357315807679003804911795226565202352127291594603943
27222414389484607402282947077135939121411276374956762365963334486336907644413697
68246281563472846765824974057419578000691802144586648218609477689380837080594949
84434451746800415081286751988931165686613628502248356969906606710480802490487720
51193358699411968177101349014181943964026288481494292632307160152196471809062608
09408509166378415773088896575579384296091317883085437564856451054998270494638533
37945347630577654790729851262538913870632998962296783120027672085783465928744379
10757523348322379799377378069872016603251470079557246627464545140089934278796264
26841923209961950882047734347976478727084053960567277758561051539259771705292286
40608785887236250432376340366655136630923555863023175371843652715323417502594258
04219993081978554133517813905223106191629194050501556554825319958491871324801106
88343133863714977516430300933932895191975095122794880664130058803182289865098581
80560359737115185
>>> s=m//N
>>> s
0
>>> 33/57820
0.00057073676928398479
с перегруженным оператором строки Python %
, используемым для заполнения нулями, чтобы увидеть полный набор повторяющихся цифр:
>>> "%01218d" % r
'0570736769283984780352819093739190591490833621584226911103424420615703908682116
91456243514354894500172950536146662054652369422345209270148737461086129367001037
70321687997232791421653407125562089242476651677620200622621930127983396748529920
44275337253545485991006572120373573158076790038049117952265652023521272915946039
43272224143894846074022829470771359391214112763749567623659633344863369076444136
97682462815634728467658249740574195780006918021445866482186094776893808370805949
49844344517468004150812867519889311656866136285022483569699066067104808024904877
20511933586994119681771013490141819439640262884814942926323071601521964718090626
08094085091663784157730888965755793842960913178830854375648564510549982704946385
33379453476305776547907298512625389138706329989622967831200276720857834659287443
79107575233483223797993773780698720166032514700795572466274645451400899342787962
64268419232099619508820477343479764787270840539605672777585610515392597717052922
86406087858872362504323763403666551366309235558630231753718436527153234175025942
58042199930819785541335178139052231061916291940505015565548253199584918713248011
06883431338637149775164303009339328951919750951227948806641300588031822898650985
8180560359737115185'