Към съдържанието
wannacode

Смятане

Проблем

Сметката на масата

Поръчал си три кафета по 2,50 € и два кроасана по 1,50 €. Плащаш с банкнота от 20 €. Колко е сметката и колко ресто трябва да получиш?

Наум става. Но касата в кафенето прави такава сметка стотици пъти на ден, с различни цени и количества. Програмата трябва да смята сама.

Идеята

Аритметичните оператори

Смяташ както на хартия: + събира, - изважда, * умножава, / дели. Тези знаци се казват оператори.

double coffee = 2.5;
double croissant = 1.5;
double total = 3 * coffee + 2 * croissant;
double change = 20 - total;
Console.WriteLine("Общо: " + total + " €");
Console.WriteLine("Ресто: " + change + " €");
Изход
Общо: 10.5 €
Ресто: 9.5 €

Редът е като в математиката: първо * и /, после + и -. Затова 3 * coffee + 2 * croissant е 7,5 + 3. Ако искаш друг ред, слагаш скоби: (2 + 3) * 4 е 20.

Има и пети оператор, %. За него е следващата идея.

По-точно, за любопитните
  • Операторите с еднакъв приоритет се смятат отляво надясно: 20 - 5 - 3 е 12, а не 18.
  • - пред число го прави отрицателно: -total.
  • При текст + не събира, а долепя. Щом отляво има текст, всичко след него се долепя като текст. Това е капанът в следващата карта.

Пробвай

Билети за концерта

Три билета по 8 € и 5 € такса за поръчката.

Какво ще отпечата програмата?

int tickets = 3;
int fee = 5;
Console.WriteLine("Общо: " + tickets * 8 + fee);
Отговор

Проблем

Среден успех 5, а не 5,67

Имаш оценки 5, 6 и 6. Средният успех е 17 / 3 = 5,67. Програмата казва друго:

int math = 5;
int physics = 6;
int english = 6;
double average = (math + physics + english) / 3;
Console.WriteLine("Среден успех: " + average);
Изход
Среден успех: 5

Записваш резултата в double, а дробната част пак я няма. Къде се изгуби?

Идеята

Цяло делено на цяло дава цяло

Когато и двете страни на / са int, делението е целочислено: резултатът е цяло число, а дробната част се отрязва. 17 / 3 е 5. Чак след това петицата се записва в double и става 5.0.

Ето средния успех от предната карта, стъпка по стъпка:

int math = 5;
int physics = 6;
int english = 6;
double average = (math + physics + english) / 3;
Console.WriteLine("Среден успех: " + average);
Стъпка по стъпка, с думи
  1. Три оценки, всяка в int: 5, 6, 6.
  2. Първо скобите: 5 + 6 + 6 = 17. Сборът също е int.
  3. 17 / 3: и двете страни са int. Колко цели групи по 3 има в 17? 5.
  4. Остатъкът 2 (това е 17 % 3) се отрязва. Резултатът е цялото число 5.
  5. Чак сега 5 се записва в double average и става 5.0. Дробната част вече я няма.
  6. Отпечатва се „Среден успех: 5“: C# не пише .0 накрая. 5,67 не се появява никъде.

Отрязаното не се губи напълно. Операторът % дава остатъка от делението: 17 % 3 е 2, защото 17 = 5 · 3 + 2.

Двете заедно разделят количество на цели части и остатък. Филмът е 135 минути:

int minutes = 135;
int hours = minutes / 60;
int rest = minutes % 60;
Console.WriteLine(hours + " ч. " + rest + " мин.");
Изход
2 ч. 15 мин.

% ще ти трябва често. Число е четно, ако n % 2 е 0. Последната цифра на число е n % 10.

По-точно, за любопитните
  • При отрицателни числа резултатът се отрязва към нулата, а остатъкът има знака на делимото. % работи и с дробни числа:
Console.WriteLine(-7 / 2);
Console.WriteLine(-7 % 2);
Console.WriteLine(7.5 % 2);
Изход
-3
-1
1.5
  • Цяло число, делено на 0, спира програмата с грешка: DivideByZeroException. При double грешка няма: 5.0 / 0 дава безкрайност, а 0.0 / 0 дава NaN („не е число“).

Пробвай

Бутилки в каси

В една каса влизат 6 бутилки. Имаш 17.

Какво ще отпечата програмата?

int bottles = 17;
int perCase = 6;
Console.WriteLine(bottles / perCase + " каси");
Console.WriteLine(bottles % perCase + " остават");
Отговор

Идеята

Превръщане между типове

За да е делението дробно, поне едната страна трябва да е double. Ако имаш int, превръщаш го: пишеш типа в скоби пред стойността. Това се казва превръщане на тип (cast).

int sum = 5 + 6 + 6;
double average = (double)sum / 3;
Console.WriteLine(average);
Console.WriteLine($"{average:F2}");
int whole = (int)9.99;
Console.WriteLine(whole);
Изход
5.666666666666667
5.67
9

(double)sum прави 17 на 17.0 и тогава делението е дробно. Ако числото е написано в кода, стига да е дробно: sum / 3.0.

Обратното, от double към int, отрязва дробната част: (int)9.99 е 9, не 10. Затова компилаторът не го прави сам: ако напишеш int whole = 9.99;, програмата не се компилира. От int към double нищо не се губи и превръщането става само: double price = 10; е 10.0.

По-точно, за любопитните
  • Превръщането е от число към число. Текст към число вече правиш с int.Parse: това е друго.
  • Символът (char) всъщност се пази като число, неговия код. Затова се превръща в int и обратно:
Console.WriteLine((int)'A');
Console.WriteLine((char)66);
int max = 2147483647;
Console.WriteLine(max + 1);
Изход
65
B
-2147483648
  • Третият ред е изненада: int стига до 2 147 483 647. Едно повече не дава грешка, а „превърта“ до най-малкото отрицателно число. За по-големи числа има long.
  • В C# има и Convert.ToInt32(9.99). Той закръгля (дава 10), а не отрязва като (int).

Пробвай

Намери грешката

Сметката за ток е 125 € и се дели между трима съквартиранти. Програмата казва, че всеки дава 41,00 €, а трябва 41,67 €. На кой ред е грешката?

Избери реда с грешката.

Идеята

Съкратени записи: += и ++

Често променяш стойност спрямо самата нея: балансът на картата намалява с всяка покупка, броячът расте с едно. За това има кратки записи:

double balance = 20;
int purchases = 0;
balance -= 4.5;
purchases++;
balance -= 3.5;
purchases++;
Console.WriteLine(purchases + " покупки, остават " + balance + " €");
Изход
2 покупки, остават 12 €
Пишеш Значи
balance -= 4.5; balance = balance - 4.5;
total += price; total = total + price;
x *= 2;, x /= 2;, x %= 2; същото с *, / и %
purchases++; purchases = purchases + 1;
seats--; seats = seats - 1;

+= работи и с текст: message += "!"; долепя удивителен знак в края.

По-точно, за любопитните

++ може да стои и пред променливата. Сам на ред няма разлика. В израз има: a++ дава старата стойност и после увеличава, ++a първо увеличава и дава новата.

int a = 5;
int b = a++;
int c = ++a;
Console.WriteLine(a + " " + b + " " + c);
Изход
7 5 7

Такъв код се чете трудно. Пиши ++ и -- сами на реда.

Идеята

Math: корен, степен, закръгляне

Пицария продава пица от 30 см на същата цена като две пици от 20 см. Кое е повече? Площта на кръг е π · r². За степента и за π има готово в Math: пишеш името и в скоби числата. Това са методи, готови парчета код. Свои ще пишеш в модул „Методи“.

double big = Math.PI * Math.Pow(15, 2);
double small = 2 * Math.PI * Math.Pow(10, 2);
Console.WriteLine($"Една от 30 см: {big:F1} кв. см");
Console.WriteLine($"Две от 20 см: {small:F1} кв. см");
Console.WriteLine(Math.Sqrt(144));
Console.WriteLine(Math.Abs(-7.5));
Изход
Една от 30 см: 706.9 кв. см
Две от 20 см: 628.3 кв. см
12
7.5

Една голяма пица е повече от две малки.

Пишеш Какво дава
Math.Sqrt(x) корен квадратен
Math.Pow(x, n) x на степен n
Math.Abs(x) абсолютната стойност (без знака)
Math.Round(x) закръгляне до цяло число
Math.PI числото π, 3,14159…

Коренът и степента връщат double, дори когато резултатът е цяло число. Ако ти трябва int, превърни го: (int)Math.Sqrt(144).

По-точно, за любопитните
  • Закръгляне на 2,5: Java и C# дават различно.
Console.WriteLine(Math.Round(2.5));
Console.WriteLine(Math.Round(3.5));
Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero));
Console.WriteLine(Math.Round(5.678, 2));
Изход
2
4
3
5.68
  • Math.Round закръгля „половинката“ към четното число: 2,5 става 2, а 3,5 става 4. Така е при банките (оттам и името „банково закръгляне“). Училищното закръгляне е с MidpointRounding.AwayFromZero. С втори аргумент закръгляш до толкова знака след запетаята: Math.Round(5.678, 2) е 5,68.
  • F2 следва езиковите настройки на компютъра. На компютър с български настройки ще видиш 706,9, а не 706.9.

Упражнение

Да смята програмата

Реши задачите в редактора си. Всяко число на входа е на отделен ред.

1. Средно на три числа. Прочети три цели числа и отпечатай средното им с два знака след запетаята. Внимавай с делението.

Вход
5
6
6
Изход
Средно: 5.67

2. Секунди в часове. Прочети брой секунди и ги раздели на часове, минути и секунди. Подсказка: в един час има 3600 секунди, а % дава каквото остава.

Вход
3725
Изход
1 ч. 2 мин. 5 сек.

3. Обем на сфера. Прочети радиуса и отпечатай обема: V = 4/3 · π · r³. Помисли колко е 4 / 3, преди да го напишеш така.

Вход
10
Изход
Обем: 4188.79 куб. см

4. Целзий във Фаренхайт. F = C · 9 / 5 + 32. Прочети температурата в градуси Целзий.

Вход
37
Изход
37.0 °C = 98.6 °F

Още задачи

  • Инчове в сантиметри. Един инч е 2,54 см. За 12 инча: 30.48 см.
  • Площ на правоъгълник. Прочети дължината и ширината, отпечатай площта (дължина · ширина).
  • Площ на квадрат. Прочети страната, отпечатай площта. Направи го веднъж с * и веднъж с Math.Pow.
  • Радиани в градуси. Градуси = радиани · 180 / π. За 3.14159: 180.00°.
  • Часове в секунди. Прочети брой часове и отпечатай колко секунди са. За 2 часа: 7200.
  • Код на символ. Прочети символ и отпечатай кода му. За A: 65. Първия символ на въведения текст вземаш с Console.ReadLine()[0]. Какво значи това, ще видим в урока за текста.

Тест

Провери се

1. Колко е 17 / 5, ако и двете числа са int?
2. Колко е 17 % 5?
3. Кой израз дава 2,5?
4. Какво дава (int)9.99?
5. Какво отпечатва Console.WriteLine("Сума: " + 2 + 3)?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·