Защо ни е това
Този урок е обобщение — няма нови оператори. Има една задача, която изглежда лесна, докато не я погледнеш отблизо, и която ще решим докрай по всички правила: анализ, диаграма, код.
Вече знаеш, че пресмятанията с дробните типове не са много точни, особено когато общият брой на цифрите на десетичните дроби е твърде голям. Алтернативата е да смятаме с правилни дроби, представени с числител и знаменател, и да превръщаме резултата в десетична дроб чак преди да го изведем.
Ключово
Две цели числа (числител и знаменател) пазят точно това, което double само приближава. Цената е, че всяка аритметична операция трябва да я напишем сами.
Задача 1 — четирите действия с правилни дроби
Условие. Напиши програми, които извършват четирите аритметични операции с правилни дроби. Числителите и знаменателите на двете дроби се въвеждат от стандартния вход — първо числителя и знаменателя на първия операнд, а след това числителя и знаменателя на втория.
Анализ на задачата
Нека дробното число x е представено с числителя си numx и знаменателя си denumx, denumx > 0, а числото y — с numy и denumy, denumy > 0.
Бележка
Отрицателните дробни числа могат да се представят и с отрицателен числител и положителен знаменател, и с положителен числител и отрицателен знаменател. За простота избираме първата възможност и се придържаме към нея.
За знаменател на резултата можем да вземем кое да е общо кратно на denumx и denumy. Най-лесното е произведението им. Оттам излизат формулите:
| Операция | Числител numz | Знаменател denumz |
|---|---|---|
| z = x + y | numx·denumy + numy·denumx | denumx·denumy |
| z = x − y | numx·denumy − numy·denumx | denumx·denumy |
| z = x · y | numx·numy | denumx·denumy |
| z = x / y | numx·denumy | denumx·numy |
За да работи програмата с максимално допустими числа, числителите и знаменателите се представят в най-мощния знаков целочислен тип — long.
Внимание
Защо не безнаковия ulong, който побира двойно по-големи числа? Защото тогава няма как да смятаме с отрицателни дроби.
Диаграма на процеса
Процесът е безусловно линеен — четири блока един под друг, точно както в грубата диаграма от предишния урок, само че вече детайлизирани.
Програмата AddRat
static void Main(string[] args)
{
long numx, denumx;
long numy, denumy;
long numz, denumz;
numx = long.Parse(Console.ReadLine());
denumx = long.Parse(Console.ReadLine());
numy = long.Parse(Console.ReadLine());
denumy = long.Parse(Console.ReadLine());
numz = numx * denumy + numy * denumx;
denumz = denumx * denumy;
Console.WriteLine(numz + "/" + denumz);
}Останалите три програми — SubRat, MulRat и DivRat — се различават само по двата реда с формулите. Точно затова си струваше да ги изведем предварително в таблица.
Още линейни задачи
Упражнения
Задача 2. Напиши конзолно приложение, което въвежда от конзолата радиус R и извежда периметъра на окръжност с този радиус и лицето на кръга със същия радиус. Указание: на променлива от дробен тип присвои приблизителна стойност на константата π.
Задача 3. Напиши конзолно приложение, което въвежда дължините на трите страни на триъгълник и извежда периметъра и лицето му. Указание: припомни си формулата на Херон.
Контрол и оценка
Задачи за самопроверка
1. Напиши програмите SubRat, MulRat и DivRat за изваждане, умножение и деление на рационални числа, като използваш формулите от урока.
2. Знаеш ли по-добър начин за намиране на знаменател при аритметичните операции? Опиши го. Какъв е видът на изчислителния процес, необходим за намирането на такъв знаменател?
3. Напиши конзолно приложение, което по зададен радиус на окръжност намира нейната обиколка и лице.
4. Представи си, че в задача 3 се въвежда освен радиус и указание дали става дума за окръжност/кръг, или за сфера/кълбо, и във втория случай трябва да се пресметнат лице на повърхността на сфера и обем на кълбо. За какъв вид изчислителен процес става дума?
Съвет
Отговорът на задача 2 е най-малкото общо кратно вместо произведението. За да го намериш, ти трябва най-голям общ делител — а той се смята с цикъл. Значи процесът вече не е линеен, а цикличен. Ще се върнем на това в урок 12.
Какво трябва да запомниш
- Дробните типове са приблизителни. Две цели числа — числител и знаменател — пазят стойността точно.
- Знаменателят на резултата може да е кое да е общо кратно; най-лесното е произведението на двата знаменателя.
- Знакът се държи в числителя — така програмата работи и с отрицателни дроби. Затова типът е
long, а неulong. - Четирите програми се различават с два реда. Когато анализът е направен добре, кодът е кратък.
- Линейният процес се разпознава веднага: няма нито един ромб в диаграмата.