Рассмотрим следующую задачу. Найти период дроби 1/81. Уверяю, что для решения не потребуется ни калькулятор, ни деление столбиком. Для начала вспомним чему равно 81*(Период). Пусть длина периода n, тогда исходная дробь запишется как:
Перепишем данное представление в следующем виде:
Последнее выражение можно представить так:
Ну а теперь то соотношение, которое мы искали:
Для нашего случая это тождество будет следующим:
Разделим левую и правую часть на 9, получим:
Первое число, составленное из одних единиц, которое делится на 9 равно 111111111, это следует из признака делимости на 9. Делить будем через сумму цифр исходного числа. Двигаемся слева направо, складываем цифры делимого и на каждом шаге записываем полученную сумму. Результат работы данного алгоритма — число 12345678,9999… Здесь надо пояснить, что когда мы достигаем крайней правой цифры, то ставим запятую и полученную сумму цифр исходного числа дублируем как бесконечную десятичную дробь. Вспоминаем, что 0,999...=1 и получаем ответ, который мы искали 12345679. Если рассмотреть более общую задачу нахождения периода дроби , то окажется, что период такой дроби имеет длину и если известен период для случая n-1, то следующий равен произведению данного периода на число вида 11111… (повторяется раз)22222… (повторяется раз)33333… (повторяется раз). Самая правая секция будет иметь вид 8888..889. Последняя цифра девятка.
Приведу код процедур, которые я использовал для проверки своих выводов.
Function GreatestCommonDivisor(x,y)
if x=y then
return x;
endif;
a=min(x,y);
if a=1 then
return 1;
endif;
b=x+y-a;
while TRUE do
c=b%a;
if c=0 then
return a;
endif;
b=a;
a=c;
enddo;
EndFunction
Function NumeratorFractionPeriod(numerator,denumerator)
// дробь a/b
a=numerator;
b=denumerator;
while b%2=0 do
b=b/2;
a=a*5;
enddo;
while b%5=0 do
b=b/5;
a=a*2;
enddo;
//наибольший общий делитель
c=GreatestCommonDivisor(a,b);
a=a/c;
b=b/c;
if b=1 then
Period=string(a);
return Period;
endif;
if a>b then
Period=string((a-a%b)/b);
a=a%b;
if a=0 then
return Period;
endif;
Period=Period+"(";
else
Period="(";
endif;
while a%10=0 do
a=a/10;
enddo;
i=a;
while TRUE do
j=0;
while i<b do
i=i*10;
j=j+1;
if j>1 then
Period=Period+"0";
endif;
enddo;
check=i-a;
if (check%b)=0 then
Period=Period+(check)/b;
break;
else
j=i%b;
Period=Period+(i-j)/b;
i=j;
endif;
enddo;
return Period+")";
EndFunction
Автор: scientes