Блок 1. Раздел 1. Тема 4

Класс
математических вычислений Math

Порой необходимо сделать более серьезные вычисления, чем сложить или помножить два числа. На практике постоянно нужно или посчитать квадратный корень, или возвести в степень, или взять модуль. Также часто нужно генерировать случайные числа, чтобы программа каждый раз вела себя по-новому, задавала уникальные вопросы, располагала персонажей на экране в других положениях и так далее. Для всего этого в Java есть встроенный класс Math.
Пусть, к примеру, есть объявление, что площадь квадратного участка земли составляет 9 соток, и вы хотите посчитать длину стороны такого участка. Сотка - это 100 квадратных метров, а значит 9 соток - это 900 кв. метров. Длина стороны будет квадратным корнем из площади квадрата. Для расчета стороны нам поможет класс Math, и вот как он работает:
// объявить дробное x и приравнять к результату вычисления 
double x = Math.sqrt (900); 
// Math.sqrt - функция sqrt класса Math. 
// Она вычисляет квадратный корень из своего параметра.
// В данном случае корень из 900 будет 30
Данный код запускает функцию sqrt, сокращенно от square root – квадратный корень. Скобки обозначают «запустить функцию с параметром», он сейчас равен 900. То есть мы вычисляем квадратный корень из 900, он равен 30, поскольку 30*30=900. Полученную десятку мы записываем в переменную икс. Если не записать результат вычисления в переменную или ещё как-то его не использовать, то он сразу стирается как ненужный.

В этом примере мы запускаем функцию, которая возвращает значение. Так устроены все вычислительные функции – они берут параметры, делают вычисления и выдают результат там же, где были вызваны. Так и здесь вместо
double x = Math.sqrt (100); 
фактически выполнится
double x = 10;  //в место вызова Math.sqrt(100) подставится результат - 10
потому что sqrt вернет число 10, и десятка подставится на место вызова sqrt. Мы вскоре сами будем писать функции, которые возвращают значение. Пока что воспользуемся библиотечными.

Класс Math содержит много функций для самых разных вычислений. Доступ к ним идет через слово Math и точку вот так:
Math.название_функции (параметр);
Посмотрим новый пример с комментариями:
package javaapplication1;
public class JavaApplication1 {
         public static void main(String[] args) {
//вызовем функцию println
		System.out.println ("Пользуемся Math");
// Объявим переменную x, равную корень из 100
		double x = Math.sqrt (100);
// Теперь объявим y, равную корню из x,
		double y = Math.sqrt (x);
// Выведем на экран значение y
		System.out.println (y);
// Попробуем посчитать корень из отрицательного числа
		double z = -10;
/* Подставим вызов sqrt прямо в println – да, так можно.
 Мы увидим NaN – not a number, т.е. не число, потому что корня из отрицательного числа не существует. */
		System.out.println (Math.sqrt (z));
/* Попробуем ещё функции. 
 Модуль или abs от absolute – абсолютный – эта операция убирает у числа знак минус. 
 Переменная z была -10, а станет просто 10 */
		z = Math.abs (z);	
/* Применим теперь возведение в степень pow – от слова power – степень.
 Pow принимает два параметра, назовем их a и b, 
они указываются в скобках через запятую. Pow вернет a в степени b. 
Например пусть a = 2, b = 3, то есть возведем 2 в степень 3 и получим 8. */
		double a = 2;
		double a_cube = Math.pow (a, 3);
		System.out.println (a_cube);
// Округлим дробное число до наименьшего целого – это ceil
		double s = Math.ceil (2.7);
// Будет 2
		System.out.println (s);
// Округлим число до наибольшего целого – это floor
		s = Math.floor (2.7);
// Будет 3
		System.out.println (s);
/* Функция signum возвращает 1, если число положительное и -1, если отрицательное. 
 Так мы можем узнать знак числа */
		double res = Math.signum (-10);
// Будет -1
		System.out.println (res);		
/* также есть все функции тригонометрии – синус sin, косинус cos и так далее. 
Число pi обозначается Math.PI. Например, sin (pi/3) будет так:  */
		res = Math.sin (Math.PI / 3);
/* Полный список функций доступен, например, на сайте официальной документации 
 и легко находится в гугл запросом «класс Math Java». 
 В качестве примера гугл выдал ссылку - http://java-help.ru/java-lang-math/ - 
 там полный список функций этого класса с примерами и описанием. 

 А вот ссылка на официальную документацию:
 https://docs.oracle.com/javase/10/docs/api/java/lang/Math.html
 Документация просто содержит описание всех функций всех стандартных классов.
 Она пока существует только на английском, но написана простым техническим языком.

 Учитесь гуглить, читать форумы, документацию, справочники, стандарт языка. 
 Огромное количество начальных вопросов подробно разобрано – ищите и найдёте! 
 Это очень важное умение для программиста, не пренебрегайте им! На нашем онлайн 
 курсе progtoday.ru преподаватели дают принципы программирования и подталкивают 
 участников к максимальной самостоятельности. */
	}
/* По достижении закрывающей фигурной скобки переменные уничтожаются.
 Поскольку это был main, вся программа завершается. */
}
Теперь давайте попробуем сделать более сложные выражения. Математические функции получают на вход число и в результате дают другое число. Поэтому можно результат одной функции сразу передавать другой. Посмотрим на примере:
// вычислим квадратный корень из 81, вычислим 2 в степени 3
// вычтем одно из другого и дадим на вход функции abs 
double y = Math.abs ( Math.sqrt (81) - Math.pow (2,3) );
// теперь y будет положительной независимо от знака разности
// это бывает удобно, когда вы не уверены в знаке результата, а вам нужен положительный.

// снова дадим результат вычисления одной функции на вход другой:
System.out.println ( Math.sqrt (81) ); // распечатать квадратный корень из 81

// Такие комбинации можно делать сколько угодно раз -
// результат предыдущей функции подается на вход следующей и так далее. 
// к примеру можно вычислить квадратный корень из двух в кубе:
double z = Math.sqrt ( Math.pow ( 2,3) );
Генерируем случайные числа
Очень часто бывает нужно получить случайные числа. Например, в следующих темах мы с вами сделаем игру в лотерею, и нужно будет генерировать случайное счастливое число, а пользователь будет его угадывать - каждый раз разное. На помощь приходит простая функция Math.random, которая при запуске возвращает очередное случайное число в диапазоне от 0 до 1. Хотите диапазон от 0 до 100? Умножьте полученное число на 100. Подробнее посмотрим в коде:
// сгенерируем и напечатаем случайное число от 0 до 1
double x = Math.random(); 
System.out.println (x); // одно случайное число
x = Math.random(); 
System.out.println (x); // уже совсем другое и заранее его предсказать невозможно

// теперь от 0 до 100
x = Math.random() * 100;

// теперь от 10 до 100
x = 10 + Math.random() * 100;

//и в общем виде
double a = 10, b = 100;
x = a + Math.random() * b;
Самое главное мы уже освоили. Теперь время решать задачи. Ответьте на несколько вопросов, чтобы лучше усвоился новый материал. Имейте в виду, некоторые ответы были освещены в темах раньше или не были освещены вообще, так что если приходится думать слишком много, то просто открывайте ответ по плюсику и читайте. Другое дело задачи из нашего задачника - только для некоторых типов задач дано решение. остальное вы должны написать сами.
Вопрос 1. Перечислите, какие функции класса Math вы знаете. Что они делают?
В этой теме мы прошли - sqrt, pow, abs, ceil, floor, sin, cos и random. На самом деле их несколько больше, см. документацию java по классу Math - https://docs.oracle.com/javase/10/docs/api/java/lang/Math.html В том числе отметим арккосинус - acos, арксинус - asin, минимум из двух числе - min, максимум - max. Очень рекомендуем в какой-либо тетрадке начать выписывать ключевые слова, принципы и так далее - когда вы пишите, ваш мозг включается на 100%, а потом будет легче вспомнить по записям.
Вопрос 2. Что значит - "функция возвращает значение"?
Когда мы пишем название функции и указываем затем круглые скобки, они запускается. Есть функции, не возвращающие никаких значений - например, распечатка. А есть функции, возвращающие значения, например - вычисление квадратного корня. Фраза "функция возвращает значение" означает, что при вызове такой функции в коде прямо вместо ее имени будет подставлено число (или набор чисел, как мы узнаем позже), которое она рассчитала.
Задача 1. Ниже дан код. Как вы думаете, почему компилятор выдает на нем ошибку?
package javaapplication1;
public class JavaApplication1 {
public static void main(String[] args) {
  int x = Math.sqrt (100); 
  System.out.println (x);
 }   
}
Решение
Большинство математических функций возвращают ответ как дробное число. А в нашем коде написано:
int x = некоторое дробное;
Получается мы сохраняем дробное число в переменную, где могут храниться только целые, т.к. мы дали ей тип int. Компилятор переживает, что мы отбрасываем дробную часть, ведь возможно в ее вычислении и состояла вся задача.

Чтобы убрать ошибку нужно написать:
double x = Math.sqrt (100);
И другой вариант:
int x = (double) Math.sqrt (100);

Когда мы слева от имени функции в скобках указываем тип, мы говорим компилятору - привести то, что справа в указанному типу несмотря ни на что. В данном случае - отбросить дробную часть, потеряв точность. Это называется приведение типов - у нас еще будет об этом целая тема.

Решайте больше задач по этому разделу здесь.
В следующей теме расскажем подробнее
о типах данных в Java