Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.12.2023, 16:59   #1
jura_k
gamer
Участник клуба
 
Аватар для jura_k
 
Регистрация: 09.05.2015
Сообщений: 1,529
По умолчанию Работа с дробями

Здравствуйте. Я написал программу для работы с арифметическими дробями. У меня ушло на это больше месяца.
Вначале нужно ввести 20 чисел, которые представляют 10 дробей. Затем программа произведет с ними некие действия и результат выведет на экран.

1. Просьба заценить.
2. Просьба протестировать.
3. Дизассемблирование приветствуется.

Платформа Win32. Программа в архиве "p147.7z".
Код:
/*	 p147
 Язык Visual C++ 6.0
	 Работа с дробями   */

/*	 147.1. Реализовать в виде модуля набор подпрограмм для выполнения
 следующих операций над обыкновенными дробями вида p / q:
	 сложение, вычитание, умножение, деление, сокращение дроби,
	 возведение дроби в степень, операции отношения.   */

class CP147Doc:public CDocument
{
protected:
	CP147Doc ();
	DECLARE_DYNCREATE (CP147Doc);

	char aa [200];	//   вводимая строка
	int ad [20];		//   вводимые целые числа
	int ag, ah, ai, aj;

	void bb ();
	void bc ();
	void bd ();		//   решение задач

	int am [20];		//   результаты
	CString an [10];
};

//   Результаты вычислений
int cc, cd;

//   Функции операций с дробями
void sum (int, int, int, int);
void subtract (int, int, int, int);
void multiply (int, int, int, int);
void divide (int, int, int, int);

void reduce (int, int);						//   сокращение дроби
void power (int, int, int);					//   возведение в степень
CString relation (int, int, int, int);		//   операции отношения

CP147Doc::CP147Doc ()
{
	aa [0] = 0;
	ag = ah = 0;
}

void CP147Doc::bb ()
{
	int a;

	ah = 1;	//   флаг - пользователь нажал <Enter>
	ai = 0;

	for (a = 0; a < 20; a++)
	{
		while ((aa [ai] < '0'  ||  aa [ai] > '9')  &&  aa [ai] != '-'  &&  aa [ai]) ai++;
		bc ();
		ad [a] = aj;	//   заносим целые числа в массив из строки ввода
	}

	bd ();		//   решение задач
}

void CP147Doc::bc ()
{
	int a;

	aj = 0;
	a = 1;
	if (aa [ai] == '-') {a = -1; ai++;}
	while (aa [ai] >= '0'  &&  aa [ai] <= '9')
	{
		aj = aj * 10 + aa [ai] - '0';
		ai++;
	}

	aj *= a;
}

void CP147Doc::bd ()		//   решение задач
{
	int a, b, c, d, e, f;
	int g [20];		//   временный массив дробей
	CString j, k;

	//   Задача 1. Тестирование работы функций.
	sum (ad [0], ad [1], ad [2], ad [3]);
	am [0] = cc;
	am [1] = cd;

	subtract (ad [0], ad [1], ad [2], ad [3]);
	am [2] = cc;
	am [3] = cd;

	multiply (ad [0], ad [1], ad [2], ad [3]);
	am [4] = cc;
	am [5] = cd;

	divide (ad [0], ad [1], ad [2], ad [3]);
	am [6] = cc;
	am [7] = cd;

	reduce (ad [0], ad [1]);
	am [8] = cc;
	am [9] = cd;

	power (ad [0], ad [1], ad [2]);
	am [10] = cc;
	am [11] = cd;

	an [0] = relation (ad [0], ad [1], ad [2], ad [3]);

	/*   147.2. Дан массив A, элементы которого - обыкновенные дроби.
	Найти сумму всех элементов и их среднее арифметическое.
	Результаты представить в виде несократимых дробей.   */

	/*   (a / b), (c / d) - временные дроби; e - переменная цикла; f - число дробей в последовательности.   */
	a = ad [0];
	b = ad [1];
	if (a || b) f = 1; else f = 0;

	reduce (a, b);
	a = cc;
	b = cd;

	for (e = 1; e < 10; e++)
	{
		c = ad [e * 2];
		d = ad [e * 2 + 1];

		if ((a || b) == 0) break;
		if ((c || d) == 0) break;

		f++;
		sum (a, b, c, d);
		a = cc;
		b = cd;
	}

	an [1].Format ("Сумма дробей %i / %i.", cc, cd);

	reduce (a, b * f);
	an [2].Format ("Среднее арифметическое дробей %i / %i.", cc, cd);

	/*   147.3. Дан массив A, элементы которого - обыкновенные дроби.
	Отсортировать его в порядке возрастания.   */

	for (a = 0; a < 20; a++) g [a] = ad [a];

	for (a = 0; a < f - 1; a++)		//   внешний цикл
		for (b = 0; b < f - 1 - a; b++)		//   внутренний цикл
		{
			subtract (g [b * 2], g [b * 2 + 1], g [b * 2 + 2], g [b * 2 + 3]);
			if (cc > 0)	//   обмен значений
			{
				c = g [b * 2];
				g [b * 2] = g [b * 2 + 2];
				g [b * 2 + 2] = c;

				c = g [b * 2 + 1];
				g [b * 2 + 1] = g [b * 2 + 3];
				g [b * 2 + 3] = c;
			}
		}

	j = "";
	for (a = 0; a < f; a++)		//   вывод последовательности дробей на экран
	{
		if (a) j += ";  ";
		k.Format ("%i / %i", g [a * 2], g [a * 2 + 1]);
		j += k;
	}

	an [3] = j;

	//   Задача 4. Генерация случайного массива.
	for (a = 0; a < 10; a++) g [a] = (int) (rand () / 32767. * 30 - 10);

	j = "";
	for (a = 0; a < 5; a++)		//   вывод массива на экран
	{
		k.Format ("%i / %i", g [a * 2], g [a * 2 + 1]);
		j += k;

		if (a < 4) j += ";  ";
	}

	an [4] = j;
}

//   Функции операций с дробями

void sum (int a, int b, int c, int d)
{
	cc = a * d + c * b;
	cd = b * d;
	reduce (cc, cd);
}

void subtract (int a, int b, int c, int d)
{
	cc = a * d - c * b;
	cd = b * d;
	reduce (cc, cd);
}

void multiply (int a, int b, int c, int d)
{
	cc = a * c;
	cd = b * d;
	reduce (cc, cd);
}

void divide (int a, int b, int c, int d)
{
	cc = a * d;
	cd = c * b;
	reduce (cc, cd);
}

void reduce (int a, int b)		//   сокращение дроби
{
	int d, e, f;

	//   1. Переходим к неотрицательным числам
	d = a;
	e = b;
	if (a < 0) a = -a;
	if (b < 0) b = -b;

	//   2. Отсекаем нулевые значения
	if (a == 0)
		if (b == 0) {cc = cd = 0; return;}
		else {cc = 0; cd = 1; return;}
	else
		if (b == 0) {cc = 1; cd = 0; return;}

	//   3. Применяем алгоритм Евклида
	while (a && b) if (a < b) b %= a; else a %= b;

	//   4. Ищем наибольший общий делитель
	f = a;
	if (f == 0) f = b;

	//   5. Сокращаем дробь
	cc = d / f;
	cd = e / f;
	if (cd < 0) {cc = -cc; cd = -cd;}
}

void power (int a, int b, int c)		//   возведение в степень
{
	int d, e, f;

	d = e = 1;
	if (c > 100) c = 100;
	reduce (a, b);
	a = cc;
	b = cd;

	for (f = 0; f < c; f++)
	{
		d *= a;
		e *= b;
	}

	cc = d;
	cd = e;
}

CString relation (int a, int b, int c, int d)		//   операции отношения
{
	int e;
	int f [6];
	CString g, h;

	for (e = 0; e < 6; e++) f [e] = 0;
	subtract (a, b, c, d);

	if (cc == 0) f [0] = 1;
	if (cc != 0) f [1] = 1;
	if (cc * cd >= 0) f [2] = 1;
	if (cc * cd <= 0) f [3] = 1;
	if (cc * cd > 0) f [4] = 1;
	if (cc * cd < 0) f [5] = 1;

	g = "";
	if (f [0]) {h = "Равно,  "; g += h;}
	if (f [1]) {h = "Не равно,  "; g += h;}
	if (f [2]) {h = "больше или равно,  "; g += h;}
	if (f [3]) {h = "меньше или равно,  "; g += h;}
	if (f [4]) {h = "больше."; g += h;}
	if (f [5]) {h = "меньше."; g += h;}

	return g;
}

void CP147View::OnDraw (CDC *pDC)
{
//   Вы ввели слишком длинный текст (8386 символов). Пожалуйста, сократите его до 8000 символов.
}
Изображения
Тип файла: png Image 2a.PNG (49.6 Кб, 0 просмотров)
Тип файла: png Image 3a.PNG (45.8 Кб, 0 просмотров)
Тип файла: png Image 4a.PNG (56.8 Кб, 1 просмотров)
Тип файла: png Image 5a.PNG (40.0 Кб, 0 просмотров)
Вложения
Тип файла: doc p147e.doc (56.0 Кб, 1 просмотров)
Тип файла: 7z p147.7z (8.0 Кб, 1 просмотров)
мой канал на Ютубе: youtube.com/@games-zz3ju/videos/
мой канал на Рутубе: rutube.ru/channel/31423139/videos/
В ожидании Кеши...
jura_k вне форума Ответить с цитированием
Старый 07.12.2023, 17:22   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Переделывайте. Сделайте струкутру/класс дробь и оперируйте ими. Забудьте про глобальные переменные, тем более для результата. А если мне надо провести операции над 3 и более дробями, я должен городить sum(sum (sum .... при этом не запутаться в параметрах и помнить про глобальные переменные? А если мне нужна промежуточная дробь, то надо копировать из глобальных каждый раз?
p51x вне форума Ответить с цитированием
Старый 07.12.2023, 19:09   #3
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,814
По умолчанию

а есть проверка, что в знаменателе одной из дроби ноль? попробуйте с нулём ввести строку
1, 5, 6, 7, 9, 0
что выдаст?
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
NetSpace вне форума Ответить с цитированием
Старый 08.12.2023, 04:41   #4
jura_k
gamer
Участник клуба
 
Аватар для jura_k
 
Регистрация: 09.05.2015
Сообщений: 1,529
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Переделывайте. Сделайте струкутру/класс дробь и оперируйте ими. Забудьте про глобальные переменные, тем более для результата. А если мне надо провести операции над 3 и более дробями, я должен городить sum(sum (sum .... при этом не запутаться в параметрах и помнить про глобальные переменные? А если мне нужна промежуточная дробь, то надо копировать из глобальных каждый раз?
Никаких структур. Во-первых, я до этой теории еще не добрался (хотя и знаю, где она находится).
Во-вторых, незачем усложнять программу - она только сложнее станет. А можно по-простому.

Так если вам надо сложить три дроби, то три дроби и пишите. Программа обработает и выдаст результат. Она написана так, что может оперировать с группой до 10 дробей (хотя я и не пробовал).
А зачем вам помнить? Это программа помнит. Пользователю необязательно.
мой канал на Ютубе: youtube.com/@games-zz3ju/videos/
мой канал на Рутубе: rutube.ru/channel/31423139/videos/
В ожидании Кеши...
jura_k вне форума Ответить с цитированием
Старый 08.12.2023, 04:44   #5
jura_k
gamer
Участник клуба
 
Аватар для jura_k
 
Регистрация: 09.05.2015
Сообщений: 1,529
По умолчанию

Цитата:
Сообщение от NetSpace Посмотреть сообщение
а есть проверка, что в знаменателе одной из дроби ноль? попробуйте с нулём ввести строку
1, 5, 6, 7, 9, 0
что выдаст?
Хрень выдаст. Не надо экспериментировать с нулями - всё равно ничего хорошего не выйдет. Скажите спасибо, что программа не повисла.
Изображения
Тип файла: jpg 6a.jpg (100.7 Кб, 0 просмотров)
мой канал на Ютубе: youtube.com/@games-zz3ju/videos/
мой канал на Рутубе: rutube.ru/channel/31423139/videos/
В ожидании Кеши...
jura_k вне форума Ответить с цитированием
Старый 08.12.2023, 04:54   #6
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от jura_k Посмотреть сообщение
Не надо экспериментировать с нулями
юзер будет делать с програмой всё, что только нафантазирует. К этому нужно готовиться


Цитата:
Сообщение от jura_k Посмотреть сообщение
Скажите спасибо, что программа не повисла.
подход - просто огонь :D

В целом - как первая поделка новичка для получения некоторого опыта - норм. MFC тут не нужно, ведь GUI даже не используется. Можно даже вот тут сделать https://www.onlinegdb.com/


Цитата:
Сообщение от jura_k Посмотреть сообщение
Никаких структур
обязательно нужно добавить ООП. Это - как раз упрощение

Цитата:
Сообщение от jura_k Посмотреть сообщение
Во-вторых, незачем усложнять программу
аха, и обычный консольный текстовый калькулятор - всё это на MFC :D Прям так упростилось всё, капец


Цитата:
Сообщение от jura_k Посмотреть сообщение
int cc, cd;

// Функции операций с дробями
void sum (int, int, int, int);
void subtract (int, int, int, int);
void multiply (int, int, int, int);
void divide (int, int, int, int);

void reduce (int, int); // сокращение дроби
void power (int, int, int); // возведение в степень
CString relation (int, int, int, int);
от мусора нужно избавляться тоже

.doc - у меня например, офиса нет на компе. чем это смотреть? Ну, ладно, в хром можно закинуть
.7z - чтобы каждый мог спокойно глянуть архив, всегда делай его zip

Последний раз редактировалось Алексей1153; 08.12.2023 в 04:57.
Алексей1153 вне форума Ответить с цитированием
Старый 08.12.2023, 04:59   #7
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

к критике от старших относись серьёзно и спокойно. Мы все проходили твой путь Эти замечания - не просто так

хех, я думал, что в архиве исходники. А там бесполезный экзешник. В доке (!!!), оказываетca, огрызок от исходников.

И как это тестировать и проверять, интересно/

Исходники нужно прикладывать в zip архиве или в txt на крайняк.

Цитата:
Язык Visual C++ 6.0
серьёзно? Где ж такую древность удалось выкопать. Там ни один стандарт ещё не поддерживается

Последний раз редактировалось Алексей1153; 08.12.2023 в 05:03.
Алексей1153 вне форума Ответить с цитированием
Старый 08.12.2023, 05:11   #8
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 965
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
Можно даже вот тут сделать https://www.onlinegdb.com/
в общем, ждём расшаренную ссылку отсюда. Там можно будет обсудить код
Сейчас нет такой возможности
Алексей1153 вне форума Ответить с цитированием
Старый 08.12.2023, 08:36   #9
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
в общем, ждём расшаренную ссылку отсюда. Там можно будет обсудить код
Сейчас нет такой возможности
Не дождетесь, там mfc нет
p51x вне форума Ответить с цитированием
Старый 08.12.2023, 08:42   #10
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
Сообщение от jura_k Посмотреть сообщение
Никаких структур. Во-первых, я до этой теории еще не добрался (хотя и знаю, где она находится).
Так доберитесь или выкиньте все классы пока. А то классы и графику мы используем, хотя не добрались, а структуру нет.

Цитата:
Сообщение от jura_k Посмотреть сообщение
Во-вторых, незачем усложнять программу - она только сложнее станет. А можно по-простому.
Усложнять? Да с вашим кодом сейчас работать практически невозможно. Параметры надо помнить и постараться не перепутать, граничные случаи не обрабатываются, вместо a + b + c или хотя бы sum(sum(a, b), c) надо помнить и постояно лазить к глобальным переменным.

Цитата:
Сообщение от jura_k Посмотреть сообщение
Так если вам надо сложить три дроби, то три дроби и пишите. Программа обработает и выдаст результат. Она написана так, что может оперировать с группой до 10 дробей (хотя я и не пробовал).
А зачем вам помнить? Это программа помнит. Пользователю необязательно.
Вы на форуме программистов, а не на маркетплейсе свою поделку продаете.
p51x вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Действия над обыкновенными дробями Alex201 Общие вопросы Delphi 4 18.06.2016 13:25
пропажа точности при расчете с дробями blackart Общие вопросы C/C++ 2 02.03.2013 14:24
Структуры, работа с дробями. Hqw33 Общие вопросы C/C++ 6 13.04.2012 18:00
Задача с дробями С++ Kerragin Помощь студентам 4 31.05.2011 20:41
Действия с простыми дробями Oda33 Помощь студентам 1 11.04.2011 19:03