Форум программистов, компьютерный форум CyberForum.ru

Перевести простую пробь в десятичную - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.79
prosst
 Аватар для prosst
0 / 0 / 0
Регистрация: 25.09.2009
Сообщений: 8
11.01.2010, 23:57     Перевести простую пробь в десятичную #1
доброго времини суток!

в программировании я новичек. мне подкинули задачку:

умеется числитель и знаменатель простой дроби - натуральные числа. дробь правильная
нада написать программу которая переводит простую пробь в десятичную и если имеется период то записывает его как в математике "0.(число в периоде)"

может ктото подскажет какую то закономерность по какой можно оперделить какие числа будут в периоде
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.01.2010, 23:57     Перевести простую пробь в десятичную
Посмотрите здесь:

C++ перевести в десятичную систему 41.5(восмиричная)
Перевести простую программку с Delphi C++
перевести число из двоичной системы в десятичную C++
Перевести заданное десятичное число в 2-ю, 8-ю, 16-ю, двоично-десятичную системы и обратно C++
C++ Написать рекурсивный алгоритм перевода из двоичной системы счисления в десятичную ( из восьмеричной и шестнадцатеричной в десятичную)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
12.01.2010, 00:20     Перевести простую пробь в десятичную #2
Цитата Сообщение от prosst Посмотреть сообщение
может ктото подскажет какую то закономерность по какой можно оперделить какие числа будут в периоде
Делаем деление столбиком (или уголком, как его там зовут), и когда при получении цифр после запятой попадётся остаток, который уже встретился ранее (тоже после запятой), между одинаковыми остатками будет период.
Day
 Аватар для Day
1149 / 954 / 57
Регистрация: 29.10.2009
Сообщений: 1,384
13.01.2010, 13:47     Перевести простую пробь в десятичную #3
Хорошая задачка!
А то все матрицы, да матрицы...
Алгоритм простой - в 5-м классе, кажется, проходили.
Пусть N - числитель, M - знаменатель ( N < M - дробь правильная)
a: N *= 10;
c = N / M; // это очередная цифра
N = N % M;
// Точка истины
goto a;
Если N стало = 0, получилась точная десятичная дробь,
вычисления заканчиваем
Как поймать возникновение периода?
Очевидно, период возникает, как только N повторит одно из своих
предыдущих значений.
Этих значений < M
Поэтому заводим массив int x[M], x[i] - номер шага, на котором N==i
По началу все x[i] = 0.
Останавливаемся тогда, когда x[N] != 0
C
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
#include <stdio.h>
#include <alloc.h>
Drob(int NN, int M)
{
  long N = NN;   // исходное значение нам еще понадобится
 // Пришлось вместо int использовать long N, т.к. при умножении на 10
 // даже такого небольшего числа, как 3720, N > MAX_INT
  int c, i, step, period, dop, flag;
  int *x;
 
  printf(" %d / %d =\n", NN, M);
  x = (int *)malloc(M * sizeof(int));
  for(i=0; i<M; i++) x[i] = 0;
  step = 1;
  while(1) {
    N *= 10;
    c = N / M;
    N = N % M;
       // Точка истины
    if (N==0) {
      printf("точная десятитичная дробь\n");
      period = 0;
      break;
    }
    if (x[N]!=0) {
      period = step - x[N];
      dop = x[N] - 1;  // Сколько цифр надо печатать до периода
      printf("Периодическая дробь, длина периода = %d dop=%d\n", period, dop);
      break;
    }
    x[N] = step;
    step++;
  }
      // Теперь число печатаем
  printf("0.");
  N = NN;
  i = 0;
  flag = 0;
  while(1) {
    if (flag==0 && period && i >= dop) {
      printf("(");
      flag = 1;  // Флаг - печатаем период
      i = 0;
    }
    N *= 10;
    c = N / M;
    printf("%d", c);
    N = N % M;
    if (N==0) break;
    if (period==0) continue; // Для точной дроби все что ниже - не нужно
    i++;
    if (flag && i >= period) {
      printf(")\n");
      break;
    }
  }
}
/*****************/
main(int argc, char *argv[])
{
   if (argc<3) exit(1);
   Drob(atoi(argv[1]), atoi(argv[2]));
}
/**************/
Запуск: drob.exe числитель знаменатель

Наверное, можно сделать и поизящнее, но этот вариант как-будто работает
prosst
 Аватар для prosst
0 / 0 / 0
Регистрация: 25.09.2009
Сообщений: 8
13.01.2010, 18:45  [ТС]     Перевести простую пробь в десятичную #4
я и не думал что все так сложно)

спс Day
Байт
 Аватар для Байт
13978 / 8809 / 1228
Регистрация: 24.12.2010
Сообщений: 15,964
08.09.2012, 10:54     Перевести простую пробь в десятичную #5
Day, ошибочка у вас. Не учтены первые нули для знаменателя > 10
Вот исправленный вариант
Перевод обыкновенной дроби в десятичную (в т.ч. периодическую)
Day
 Аватар для Day
1149 / 954 / 57
Регистрация: 29.10.2009
Сообщений: 1,384
08.09.2012, 11:14     Перевести простую пробь в десятичную #6
Байт, спасибо за критику и исправления.
Но и ты не без греха.
У тебя 1/11 = 0.0(90)
Арифметически это верно, но положено все-таки 0.(09)
Так что давай думать дальше...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.09.2012, 23:47     Перевести простую пробь в десятичную
Еще ссылки по теме:

C++ перевести число с любой численной системы (2,8,16) в десятичную
C++ Как перевести число с E в десятичную систему счисления?
Перевести число из двоичной записи в десятичную C++

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

Или воспользуйтесь поиском по форуму:
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
08.09.2012, 23:47     Перевести простую пробь в десятичную #7
C++
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
 
class RepeatingDecimal
{
public:
    typedef unsigned number_type;
    RepeatingDecimal(number_type numerator, number_type denominator);
    friend std::ostream& operator<<(std::ostream& out, const RepeatingDecimal& repeatingDecimal);
private:
    std::string resultAsString;
};
 
RepeatingDecimal::RepeatingDecimal(number_type numerator, number_type denominator)
{
    std::ostringstream sout;
    sout.exceptions(std::ostringstream::badbit | std::ostringstream::failbit);
    sout << numerator / denominator;
    numerator %= denominator;
    if (numerator != 0)
    {
        sout << '.';
        std::vector<number_type> digits, remainders{numerator};
        while (true)
        {
            numerator *= 10;
            digits.push_back(numerator / denominator);
            numerator %= denominator;
            auto repetitionStartRem =
                std::find(remainders.begin(), remainders.end(), numerator);
            if (repetitionStartRem != remainders.end())
            {
                auto repetitionStart =
                    digits.begin() + (repetitionStartRem - remainders.begin());
                std::copy(
                    digits.begin(), repetitionStart,
                    std::ostream_iterator<number_type>(sout)
                    );
                sout << '(';
                std::copy(
                    repetitionStart, digits.end(),
                    std::ostream_iterator<number_type>(sout)
                    );
                sout << ')';
                break;
            }
            remainders.push_back(numerator);
        }
    }
    resultAsString = sout.str();
}
 
std::ostream& operator<<(std::ostream& out, const RepeatingDecimal& repeatingDecimal)
{
    return out << repeatingDecimal.resultAsString;
}
 
int main(int argc, char* argv[])
{
    using namespace std;
 
    if (argc < 3)
    {
        cerr << "Error: too few arguments" << endl;
        return 1;
    }
 
    istringstream argin;
    unsigned numerator, denominator;
    argin.str(argv[1]);
    argin >> numerator;
    if (!argin || argin.peek() != istringstream::traits_type::eof())
    {
        cerr << "Error: invalid argument: " << argv[1] << endl;
        return 1;
    }
    argin.clear();
    argin.str(argv[2]);
    argin >> denominator;
    if (!argin || argin.peek() != istringstream::traits_type::eof())
    {
        cerr << "Error: invalid argument: " << argv[2] << endl;
        return 1;
    }
    cout << RepeatingDecimal(numerator, denominator);
    return 0;
}
Yandex
Объявления
08.09.2012, 23:47     Перевести простую пробь в десятичную
Ответ Создать тему
Опции темы

Текущее время: 16:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru