Смятане
Проблем
Сметката на масата
Поръчал си три кафета по 2,50 € и два кроасана по 1,50 €. Плащаш с банкнота от 20 €. Колко е сметката и колко ресто трябва да получиш?
Наум става. Но касата в кафенето прави такава сметка стотици пъти на ден, с различни цени и количества. Програмата трябва да смята сама.
Идеята
Аритметичните оператори
Смяташ както на хартия: + събира, - изважда, * умножава, / дели. Тези знаци се казват оператори.
double coffee = 2.5;double croissant = 1.5;double total = 3 * coffee + 2 * croissant;double change = 20 - total;System.out.println("Общо: " + total + " €");System.out.println("Ресто: " + 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;System.out.println("Общо: " + tickets * 8 + fee);* се смята първо: tickets * 8 е 24. После отляво надясно: „Общо: “ + 24 е текстът „Общо: 24“, а към него се долепя 5. За да излезе 29, сметката трябва да е в скоби: "Общо: " + (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;System.out.println("Среден успех: " + average);Среден успех: 5.0Записваш резултата в double, а дробната част пак я няма. Къде се изгуби?
Идеята
Цяло делено на цяло дава цяло
Когато и двете страни на / са int, делението е целочислено: резултатът е цяло число, а дробната част се отрязва. 17 / 3 е 5. Чак след това петицата се записва в double и става 5.0.
Ето средния успех от предната карта, стъпка по стъпка:
int math = 5;int physics = 6;int english = 6;double average = (math + physics + english) / 3;System.out.println("Среден успех: " + average);Стъпка по стъпка, с думи
- Три оценки, всяка в int: 5, 6, 6.
- Първо скобите: 5 + 6 + 6 = 17. Сборът също е int.
- 17 / 3: и двете страни са int. Колко цели групи по 3 има в 17? 5.
- Остатъкът 2 (това е 17 % 3) се отрязва. Резултатът е цялото число 5.
- Чак сега 5 се записва в double average и става 5.0.
- Отпечатва се „Среден успех: 5.0“. 5,67 не се появява никъде.
Отрязаното не се губи напълно. Операторът % дава остатъка от делението: 17 % 3 е 2, защото 17 = 5 · 3 + 2.
Двете заедно разделят количество на цели части и остатък. Филмът е 135 минути:
int minutes = 135;int hours = minutes / 60;int rest = minutes % 60;System.out.println(hours + " ч. " + rest + " мин.");2 ч. 15 мин.% ще ти трябва често. Число е четно, ако n % 2 е 0. Последната цифра на число е n % 10.
По-точно, за любопитните
- При отрицателни числа резултатът се отрязва към нулата, а остатъкът има знака на делимото.
%работи и с дробни числа:
System.out.println(-7 / 2);System.out.println(-7 % 2);System.out.println(7.5 % 2);-3-11.5- Цяло число, делено на 0, спира програмата с грешка:
ArithmeticException: / by zero. Приdoubleгрешка няма:5.0 / 0дава безкрайност, а0.0 / 0даваNaN(„не е число“).
Пробвай
Бутилки в каси
В една каса влизат 6 бутилки. Имаш 17.
Какво ще отпечата програмата?
int bottles = 17;int perCase = 6;System.out.println(bottles / perCase + " каси");System.out.println(bottles % perCase + " остават");17 / 6 е 2 цели каси (12 бутилки), а 17 % 6 е остатъкът: 5 бутилки, които не пълнят каса.
Идеята
Превръщане между типове
За да е делението дробно, поне едната страна трябва да е double. Ако имаш int, превръщаш го: пишеш типа в скоби пред стойността. Това се казва превръщане на тип (cast).
int sum = 5 + 6 + 6;double average = (double) sum / 3;System.out.println(average);System.out.printf("%.2f%n", average);int whole = (int) 9.99;System.out.println(whole);5.6666666666666675.679(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.
По-точно, за любопитните
- Превръщането е от число към число. Текст към число вече правиш с
Integer.parseInt: това е друго. - Символът (
char) всъщност се пази като число, неговия код. Затова се превръща вintи обратно:
System.out.println((int) 'A');System.out.println((char) 66);int max = 2147483647;System.out.println(max + 1);65B-2147483648- Третият ред е изненада:
intстига до 2 147 483 647. Едно повече не дава грешка, а „превърта“ до най-малкото отрицателно число. За по-големи числа имаlong.
Пробвай
Намери грешката
Сметката за ток е 125 € и се дели между трима съквартиранти. Програмата казва, че всеки дава 41,00 €, а трябва 41,67 €. На кой ред е грешката?
Избери реда с грешката.
125 / 3 е целочислено и дава 41. Превръщането идва чак след това и прави 41 на 41.0. Поправката е превръщането да е преди делението: (double) bill / people.Идеята
Съкратени записи: += и ++
Често променяш стойност спрямо самата нея: балансът на картата намалява с всяка покупка, броячът расте с едно. За това има кратки записи:
double balance = 20;int purchases = 0;balance -= 4.5;purchases++;balance -= 3.5;purchases++;System.out.println(purchases + " покупки, остават " + balance + " €");2 покупки, остават 12.0 €| Пишеш | Значи |
|---|---|
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;System.out.println(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);System.out.printf("Една от 30 см: %.1f кв. см%n", big);System.out.printf("Две от 20 см: %.1f кв. см%n", small);System.out.println(Math.sqrt(144));System.out.println(Math.abs(-7.5));Една от 30 см: 706.9 кв. смДве от 20 см: 628.3 кв. см12.07.5Една голяма пица е повече от две малки.
| Пишеш | Какво дава |
|---|---|
Math.sqrt(x) |
корен квадратен |
Math.pow(x, n) |
x на степен n |
Math.abs(x) |
абсолютната стойност (без знака) |
Math.round(x) |
закръгляне до цяло число |
Math.PI |
числото π, 3,14159… |
Коренът и степента връщат double, дори когато резултатът е цяло число (затова 12.0). Ако ти трябва int, превърни го: (int) Math.sqrt(144).
По-точно, за любопитните
- Закръгляне на 2,5: Java и C# дават различно.
System.out.println(Math.round(2.5));System.out.println(Math.round(3.5));System.out.println(Math.round(5.678 * 100) / 100.0);345.68Math.roundзакръгля „половинката“ нагоре и връщаlong, неint. За два знака след запетаята умножаваш по 100, закръгляш и делиш на100.0. Ако е само за печат, по-удобно еprintf("%.2f").
- printf следва езиковите настройки на компютъра. На компютър с български настройки ще видиш
706,9, а не706.9.
Упражнение
Да смята програмата
Реши задачите в редактора си. Всяко число на входа е на отделен ред.
1. Средно на три числа. Прочети три цели числа и отпечатай средното им с два знака след запетаята. Внимавай с делението.
566Средно: 5.672. Секунди в часове. Прочети брой секунди и ги раздели на часове, минути и секунди. Подсказка: в един час има 3600 секунди, а % дава каквото остава.
37251 ч. 2 мин. 5 сек.3. Обем на сфера. Прочети радиуса и отпечатай обема: V = 4/3 · π · r³. Помисли колко е 4 / 3, преди да го напишеш така.
10Обем: 4188.79 куб. см4. Целзий във Фаренхайт. F = C · 9 / 5 + 32. Прочети температурата в градуси Целзий.
3737.0 °C = 98.6 °FОще задачи
- Инчове в сантиметри. Един инч е 2,54 см. За 12 инча:
30.48 см. - Площ на правоъгълник. Прочети дължината и ширината, отпечатай площта (дължина · ширина).
- Площ на квадрат. Прочети страната, отпечатай площта. Направи го веднъж с
*и веднъж сMath.pow. - Радиани в градуси. Градуси = радиани · 180 / π. За 3.14159:
180.00°. - Часове в секунди. Прочети брой часове и отпечатай колко секунди са. За 2 часа: 7200.
- Код на символ. Прочети символ и отпечатай кода му. За
A: 65. Първия символ на въведения текст вземаш сin.nextLine().charAt(0). Какво значи това, ще видим в урока за текста.
Тест