Форум программистов, компьютерный форум, киберфорум
Pascal ABC
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/88: Рейтинг темы: голосов - 88, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 05.02.2018
Сообщений: 20
1

Напишите программу, которая переводит правильную дробь в десятичную, выделив (если нужно), период дроби

09.02.2018, 23:24. Показов 17113. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Напишите программу, которая переводит правильную дробь в десятичную, выделив (если нужно), период дроби.

Входные данные
Входная строка содержит два числа M и N , разделённых пробелами. Гарантируется, что M < N .

Выходные данные
Программа должна вывести десятичную запись дроби , выделив (если нужно) её период. В качестве разделителя целой и дробной части используйте запятую.

Примеры
входные данные
1 2
выходные данные
0,5
входные данные
3 14
выходные данные
0,2(142857)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.02.2018, 23:24
Ответы с готовыми решениями:

По заданным M и N получить период дроби M/N, если дробь конечная, вывести 0
По заданным M и N получить период дроби M/N, если дробь конечная, выводим 0. Пример: 1/2, выводим...

Написать программу, которая переводит числа с шестнадцатеричной системы в десятичную
С использованием функции hex, а также без неё.

Составить программу, которая переводит число А, заданный в двоичной системе счисления в десятичную
Составить программу, которая переводит число А, заданный в двоичной системе счисления, в число...

Напишите программу, которая переводит гривны в $
напишите программу, которая переводит гривны в $, DM c комментариями?

3
1755 / 1347 / 1407
Регистрация: 28.10.2016
Сообщений: 4,267
10.02.2018, 01:44 2
Что-то вроде того
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var n, m, dot: integer;
    s: string;
begin
  read(n, m);
  s := FloatToStr(n / m);
  dot := pos('.', s);
  if (length(copy(s, dot, length(s) - dot)) <> 1) then begin
    insert('(', s, dot + 2);
    insert(')', s, length(s) + 1);
  end;
  delete(s, dot, 1);
  insert(',', s, dot);
  writeln(s);
end.
2
Модератор
10007 / 5364 / 3338
Регистрация: 17.08.2012
Сообщений: 16,342
11.02.2018, 01:22 3
Лучший ответ Сообщение было отмечено ZX Spectrum-128 как решение

Решение

Hitoku, я даже и не знаю, что сказать... Не решение. 1/47, например?

Добавлено через 3 часа 5 минут
Hitoku, гляди. Не оптимизировал. Алгоритм в общих чертах:

Любая правильная или неправильная дробь представима в виде c,r(p), где с - целая часть, r - предпериод, p - период дроби. Например, 3/14=0,2142857142857142857...=0,2(142857): 0 - целая часть, 2 - предпериод, 142857 - период. Целая часть есть всегда, а вот есть ли предпериод и / или период - это нужно выяснять.

Сразу выделяем и печатаем целую часть дроби, и сокращаем дробь.

Теперь у нас есть дробь m/n, причём будем считать, что m < n, и m и n - взаимно простые (мы уже выделили целую часть дроби и сократили дробь).

Вычисление десятичных цифр дроби, очевидный цикл: d = 10m div n - цифра, m = 10m mod n - остаток числителя для вычисления следующей цифры.

О предпериоде. Выяснено, что длина предпериода равняется максимальной степени чисел вида 2p и 5q, которые делят знаменатель. В самом деле, если знаменатель представим в виде n=2p5qz, и пусть с=max(p, q), тогда

https://www.cyberforum.ru/cgi-bin/latex.cgi?<br />
\frac{m}{n}=\frac{m}{2^p5^qz}=\left. \frac{2^c5^cm}{2^p5^qz}\right/10^c=\left. \frac{2^{c-p}5^{c-q}m}{z}\right/10^c<br />

Вычисляем длину предпериода и печатаем его.

О периоде. Выяснено, что длина периода равна количеству разрядов числа, составленных из цифры 9, делящегося на z.

Вычисляем длину периода и печатаем его.

Конец алгоритма.

Пример: 62/28.
Целая часть: 62 div 28 = 2 - печатаем.
Выделяем целую часть из дроби: 62 mod 28 = 6, получили правильную дробь 6/28.
Сокращаем, НОД(6, 28)=2, получаем 3/14.
Определяем длину предпериода: 14=21507, максимальная степень при 2 и 5 равна 1, значит, длина предпериода равна 1.
Печатаем предпериод: d = 30 div 14 = 2 - двойку и печатаем, остаток числителя дроби m = 30 mod 14 = 2.
вычисляем длину предпериода, выясняем, что 9, 99, 999, 9999, 99999 на z=7 не делятся, а 999999 делится. Следовательно, длина периода будет 6. Здорово, правда? Только вот есть подводный камень: длина периода может быть очень большой, и эти девятки ни в какой uint64 не влезут. Можно пойти экстенсивным путём, и применить тип BigInteger, но лучше делить по модулю z, умножая на 10 остаток от деления на z, и снова получать остаток от деления на z, пока остаток не станет равным 0, например, для этого случая:

ШагЧто делимОстатокПримечание
192считаем, что первый остаток был равен 0, приписываем к нему 9, получаем 9
2291предыдущий остаток был 2, приписываем 9, получаем 29
3195предыдущий остаток был 1, приписываем 9, получаем 19
4593просто, правда?
5394 
6490ура, наконец-то остаток равен 0

Так, для сравнения, с девятками:

ШагЧто делимОстаток
192
2991
39995
499993
5999994
69999990

Остатки те же. Но в первом случае "что делим" не превосходит 10(z-1).

Что получилось (для простоты писал для сдачи на проверочный сайт, без контроля ввода и интерфейса):
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var
  m, n, p, q, k, z: longint;
 
begin
  //вводим
  readln(m, n);
  //печатаем целую часть дроби
  write(m div n);
  //избавляемся от целой части дроби
  m := m mod n;
  if m > 0 //если числитель > 0, то есть дробная часть
    then begin
      write(','); //печатаем десятичную запятую, можно и десятичную точку.
      //сокращаем дробь, находим НОД (алгоритм Евклида)
      p := m; //будущий НОД
      q := n;
      while p <> q do
        if q > p
          then q := q - p
          else p := p - q;
      //сокращаем дробь
      m := m div p;
      n := n div p;
      //находим длину предпериода дроби (максимум из количества делителей 2 и 5)
      p := 0; //будущая длина предпериода
      q := 0;
      z := n; //будущий остаток знаменателя после деления на 2 и на 5
      while z mod 2 = 0 do
        begin
          inc(p);
          z := z div 2
        end;
      while z mod 5 = 0 do
        begin
          inc(q);
          z := z div 5
        end;
      if p < q then p := q;
      //печатаем предпериод дроби
      for k := 1 to p do
        begin
          m := m * 10;
          write(m div n);
          m := m mod n
        end;
      //если есть период, находим его длину и печатаем
      if z > 1 //если делители знаменателя не только 2 и 5, то есть период
        then begin
          write('(');
          q := 9; //первое число вида 9999999999999999999999999999999999999...
          p := 1; //количество разрядов в числе вида (см. выше)
          while q mod z > 0 do //пока число 999.. не разделится нацело на z, цикл
            begin
              inc(p); //на один разряд больше
              q := q mod z * 10 + 9 //делим 999.. по модулю z, во избежание переполнения
            end;
          //печатаем цифры периода
          for k := 1 to p do
            begin
              m := m * 10;
              write(m div n);
              m := m mod n
            end;
          write(')')
        end
    end;
  writeln
end.
Наверное, можно немножко соптимизировать, есть повторяющиеся фрагменты, может, в подпрограмму их выделить, может, кое-где ускорить, типа, заменить div 2 на shr 1, ещё всяких блох половить... Неохота.

Проверка. Программа выдерживает прямое попадание дроби maxlongint/(maxlongint div 10)=2147483647/214748364, результат:

10,00(00000325962902329723918176158957839604310093836151413009134728495533497987
43984843581858439675936250671506861863683394579900035932287707672594888778756889
62175283440110398233348124598518478119814686923528786463770219921209737364984070
37922766200910382721239264015999674856661538990816246683956111535266457256922339
1150025245361124148075)


Виндовый калькулятор нервно курит в сторонке, но как бы намекает, что всё верно:

10,000000032596290232972391817616

Ужос... Без применения деления по модулю для выяснения длины периода нужно было бы число из 336 девяток...
5
0 / 0 / 0
Регистрация: 15.12.2020
Сообщений: 1
15.12.2020, 00:26 4
Cyborg Drone, мужик ты просто гений, спасибо тебе за ответ, зарегался для этого, удачки)
0
15.12.2020, 00:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.12.2020, 00:26
Помогаю со студенческими работами здесь

Найти период разложения в бесконечную периодическую десятичную дробь
Найдите период разложения в бесконечную периодическую десятичную дробь числа, обратного к данному...

Составить программу, которая для натуральных чисел m и n вычисляет период десятичной дроби m/n
Помогите пожалуйста сделать такую интересную программу(а то все перепробывал нифига не выходит)...

Напишите программу, которая переводит переданное ей целое число в двоичный код
Напишите программу, которая переводит переданное её целое число (возможно, отрицательное) в...

Напишите программу, которая переводит неотрицательное целое число в четырёхзначный шестнадцатеричную систему
Напишите программу, которая переводит переданное ей неотрицательное целое число в четырёхзначный...

Даны две дроби A/B и C/D. Составить программу умножения дроби на дробь.
2. Даны две дроби A/B и C/D (A, B, C, D — натуральные числа). Составить программу умножения дроби...

Напишите программу, которая переводит переданное её целое число (возможно, отрицательное) в шестнадцатеричный код
Напишите программу, которая переводит переданное её целое число (возможно, отрицательное) в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru