Клас Math

Відкрита

1. Тригонометричні функції в Java

Раніше, вивчаючи округлення чисел, ми ознайомилися з класом Math і деякими його методами. Зараз ми розглянемо цей клас докладніше.

У класі Math, на що нібито натякає ця назва, зібрано найбільш вживані програмістами математичні функції. Ось найцікавіші з них:

Метод Опис
double sin(double d)
Повертає синус кута d, заданого в радіанах
double cos(double d)
Повертає косинус кута d, заданого в радіанах
double tan(double d)
Повертає тангенс кута d, заданого в радіанах
double asin(double d)
Повертає арксинус
double acos(double d)
Повертає арккосинус
double atan(double d)
Повертає арктангенс
double sinh(double d)
Повертає гіперболічний синус
double cosh(double d)
Повертає гіперболічний косинус
double tanh(double d)
Повертає гіперболічний тангенс

Функції Math.sin(), Math.cos() і Math.tan() отримують кут, заданий в радіанах. Щоб перетворити кути з градусів у радіани й навпаки, у класі Math є дві спеціальні функції:

Метод Опис
double toRadians(double angdeg)
Перетворює кут із градусів у радіани
double toDegrees(double angrad)
Перетворює кут із радіанів у градуси

До речі, у класі Math є не тільки функції, а ще й дві змінні-константи (статичні поля класу):

Константа Опис
double Math.PI
Число «Пі», що дорівнює 3.141592653589793
double Math.E
Число «Е», що дорівнює 2.718281828459045

Всі ці функції можуть стати вам у великій пригоді, якщо ви захочете писати власні ігри, працювати з графікою або просто обчислити відстань на карті.

Приміром, якщо вам потрібно обчислити sin(45°), це можна зробити отак:

Math.sin( Math.toRadians(45) )

Приклад використання:

public class Main
{
   public static int N = 10;

   public static void drawValue(double y)
   {
     int value = (int) (y * N) + N;
     for (int i = 0; i < 2 * N; i++)
     {
       char c = i == N ? '|': '.';
       if (i == value)
         c = '*';
       System.out.print(c);
     }
     System.out.println();
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10 * N; i++)
     {
       double x = i * 1.0 / N;
       double y = Math.sin(x);
       drawValue(y);
     }
   }
}

9
Задача
Java Syntax Zero,  9 рівень1 лекція
Недоступна
Утилітний клас: частина 1
Утилітний клас: частина 1

2. Алгебраїчні функції в Java

Здебільшого програмісту з головою вистачає шкільної математики: навіть синуси й косинуси в коді трапляються дуже рідко. Найчастіше вони потрібні під час роботи з іграми, картами або ігровими движками. 90 % програмістів із цим ніколи не стикаються.

Але, крім геометрії, програмістам іноді доводиться використовувати й алгебраїчні функції. І, звичайно ж, клас Math містить найпоширеніші з них:

Метод Опис
double sqrt(double a)
квадратний корінь із a
double cbrt(double a)
кубічний корінь із a
double pow(double a, double b)
піднесення до степеня: ab
double exp(double a)
експонента: ea
double log(double a)
натуральний логарифм a: ln(a)
double log10(double a)
десятковий логарифм a: log10a
double log1p(double x)
натуральний логарифм x + 1: ln(x + 1)
double expm1(double x)
ex-1

Якщо вам потрібен квадратний або кубічний корінь із числа, для цього є функції sqrt(a) і cbrt(a).

Корінь із числа 2 можна обчислити так:

Math.sqrt(2)

Якщо ви хочете отримати корінь більш високого степеня, скористайтеся функцією піднесення до степеня: a в степені ¼ — це й буде корінь четвертого степеня і т. д.

Math.pow(2, 0.25)

Для роботи з логарифмами й експонентою є функції log(a) — натуральний логарифм і exp(x) — експонента. Для обчислення десяткового логарифма є функція log10(a).

Якщо вам потрібен логарифм числа b за основою a, скористайтеся простою формулою: logab = ln(b) / ln(a)

Корисні функції

Останні дві функції log1p() і expm1() можуть вам знадобитися, якщо ви виконуєте обчислення з дуже маленькими значеннями x.

У разі додавання дуже маленького значення змінної double до дуже великого часто виникає ситуація, коли дуже маленьке значення просто ігнорується (відкидається) як незначуще. Це, власне, і відбуватиметься, якщо використовувати функції log() і exp(). Тому програмісти придумали функції, що повертають лише саме ту «маленьку значущу частину»

Приклад:

Вам треба знайти натуральний логарифм числа 1 + x, де х дорівнює 10-20. Ви просто не зможете передати це число у функцію log(), оскільки якщо додати 1 і 10-20 одне до одного, одержимо 1. 10-20 — дробова частина настільки маленька, що її буде відкинуто від суми повністю.

А оскільки в математиці часто доводиться обчислювати log() чисел, близьких до 1, програмісти придумали спосіб обійти цю проблему: передати у функцію не саме число, а тільки різницю між ним і 1.


9
Задача
Java Syntax Zero,  9 рівень1 лекція
Недоступна
Утилітний клас: частина 2
Утилітний клас: частина 2

3. Мінімум і максимум

І ще дві корисні функції — це min(a, b) і max(a, b). Перша, як ви вже, напевно, здогадуєтеся, повертає менше з двох чисел:

Math.min(a, b)

А друга — більше з двох чисел:

Math.max(a, b)

Навіщо ж потрібні ці функції, якщо завжди можна написати if або навіть використати тернарний оператор a < b ? a : b?

Вся річ у читабельності коду. Іноді код і без того перевантажений if-ами, і хочеться використати компактніший запис. Порівняйте:

Код Опис
int x = 0;
if (x-5+y*20 < x*x+y*y)
   x = x-5+y*20;
else
   x = x*x+y*y;
Найдовший запис формули за допомогою if-else
int x = x-5+y*20 < x*x+y*y ? x-5+y*20 : x*x+y*y;
Запис за допомогою тернарного оператора. Мінуси:
– громіздкий код
– двічі виконуються обчислення
int a = x-5+y*20;
int b = x*x+y*y;
int x = a < b ? a : b;
Хороший запис, але трохи надлишковий
int x = Math.min(x-5+y*20, x*x+y*y);
В самий раз

4. Мінімум і максимум з кількох чисел

Є ще один корисний спосіб застосування функцій min() і max().

Це обчислення мінімуму (або максимуму) з кількох чисел або змінних. Функції дуже зручно викликати одну в одній.

Отак можна записати мінімум із 3-х чисел:

Math.min(a, Math.min(b, c))

А що? Дуже зручно: знаходимо мінімум із пари чисел, а відтак повертаємо менше число зі знайденого й того, що залишилося.

Найменше з чотирьох чисел отримуємо аналогічно:

Math.min(a, Math.min(b, Math.min(с, d)))

Проте можна перетворити цю формулу на зрозумілішу:

Math.min(Math.min(a, b), Math.min(c, d))

Для функції max() усі дії виконуються аналогічно.

Якби ми використовували оператор if-else або тернарний оператор, ці записи були б дещо громіздкими. А використання функцій min() і max() — просто ідеальне рішення.


9
Задача
Java Syntax Zero,  9 рівень1 лекція
Недоступна
Мінімальний елемент масиву
Мінімальний елемент масиву
Коментарі (18)
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
ivan
Рівень 10
30 липня 2024, 17:35
Задача про масив злам мені мозок допомогли коментарі...
Гаркін
Рівень 14
5 березня 2024, 20:19
Тут лише я почуваюсь тупеньким, коли розбирав drawValue ? (фіг-вам. Я не розібрав. Бо перемножувати усі ті формули... та ну його...). І це лише мені ось цей рядок був новим
char c = i == N ? '|': '.';
і (м'яко кажучі) не зовсім зрозумілим? (так, через деякий час я зрозумів що то тернарний оператор, і чому тут викорисовується char ... Але) Ну ок...
Гаркін
Рівень 14
5 березня 2024, 21:04
Ох йо… треба відпочивати . Знали б Ви, скільки мені часу знадобилось, щоб розібратись, що рядок double sin(double d) то є метод (який належить до класу Math ) sin , а в дужках double d то є опис параметрів того методу (тобто для його роботи треба вказати d, яке повинно бути дійсним числом, на що і вказує double у дужках). Але є трабл – я не розумію що то за double на початку. Пофіг. Я виконую одне завдання і відпочивати.
Olexandr
Рівень 1
17 листопада 2023, 18:32
Да ладно, рекурсия))) Я выполнил - вручную прописав все десять переменных и их сравнение))) Потом уже посмотрел, как это можно сделать циклом) Задача отличная.
les_yeux_blancs QA Automation Engineer
21 квітня 2023, 21:13
Імхо, останню задачу варто давати після того, як познайомите учнів з поняттям рекурсії (хоча, можливо, у дефолтному розкладі з нуля ця лекція і іде пісня неї) Ось рішення:
public static int min(int[] ints) {
    if (ints.length == 2) {
        return Math.min(ints[0], ints[1]);
    }

    return Math.min(ints[0], min(Arrays.copyOfRange(ints, 1, ints.length)));
}
14 травня 2023, 02:33
Задачу можна виконати без використання рекурсії
Antek_Ukraine
Рівень 14
Expert
28 червня 2023, 13:09
Навіщо? Проходимо циклом fori по масиву (i=0,i<ints.length(), i++), порівнюючи КОЖНИЙ елемент масиву ints з змінною min (її ініціалізував як Integer.MAX_VALUE) метод повертає ту саму min Прийняло з першого разу
Vitalii Backend Developer
14 серпня 2023, 13:35
трохи оптимальніше min відпочатку присвоїти значення першого елемента масива.
hidden #3421731
Рівень 28
23 березня 2024, 16:42
А мені сподобався спосіб.Не стандартно якось використати метод який ти створюєш в методі яки ти створюєш😁.Я б до такого точно не додумався.
bogdan kravchuk
Рівень 11
15 березня 2023, 16:26
Чомусь цей рівень дуже важкий для мене. поопередні було все зрозуміло це шось взагалі не допетраю...
FAUST_ua
Рівень 29
15 липня 2022, 22:12
майже зломав голову об останню задачу..
Lipovskyi Volodymyr
Рівень 36
11 травня 2022, 15:31
В другій задачі треба закоментувати пів коду, щоб працювало)
shved IT
Рівень 26
1 березня 2022, 19:00
for (int number : ints) { min = Math.min(min, number); } return min; } что значит условие в скобках? для
Me Lex
Рівень 12
20 березня 2022, 19:19
вот и мне интересно но я сделал по своему без подсказки и у меня получилось через (int i = 1 ; i<ints.length; i++)
Olena
Рівень 14
5 серпня 2022, 14:26
foreach цикл идет по каждому вашему элементу массива, происходит присвоение текущего эл-та массива в переменную number и в
min = Math.min(min, number);
когда передаете number по сути обращаетесь к текущему эл-ту искомого массива int[] ints . Видимо, foreach использовали потому, что у нас нет явной размерности []ints
Roma Chernesh
Рівень 16
21 грудня 2022, 19:34
Щодо for (number : ints) - це цикл foreach. Якщо коротко, то ось два різні спобоба написати одне й теж саме: 1) цикл for: for (int i = 0; i < ints.length; i++) { int number = ints[i] } 2) цикл foreach: for (number:ints) { } Сходу може бути незрозуміло, тому раджку почитати статтю про цей цикл: https://javarush.com/groups/posts/for-each-java
Александр
Рівень 12
8 листопада 2021, 16:38
как все таки правильно: 1) Math.sin(Math.toRadians(a)); или так 2) Math.sin(toRadians(a));
Axis
Рівень 12
24 січня 2022, 13:41
там уже импортирован пакет import static java.lang.Math.toRadians; тобишь - второй вариант