Объект Math

типы≈ 7 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

Math — не класс и не функция, а объект-склад: полка с готовыми формулами. Ничего не нужно создавать через new, всё вызывается прямо у него: Math.round(4.7), Math.max(1, 9).

Разделы темы:·

Из дробного числа почти всегда нужно получить целое: страниц в списке, пикселей, товаров на складе. За это отвечают четыре метода, и отличаются они только направлением, в которое «уезжает» число.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

На положительных числах floor и trunc дают одно и то же, поэтому разницу между ними легко не заметить — до первого минуса. О нём следующий раздел.

Отдельного метода нет, но есть приём: умножить, округлить, поделить обратно. Он не всесилен, и причина та же, что у toFixed: почему записанное в коде 1.005 хранится чуть меньше, чем выглядит, разбирает статья «Числа: точность и округление». Здесь важно следствие: «пограничное» число уезжает не туда.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

floor и ceil двигают число по числовой прямой: первый — влево, второй — вправо. trunc двигает его к нулю, то есть для отрицательных чисел — вправо. Поэтому Math.floor(-1.2) даёт −2, а Math.trunc(-1.2) даёт −1.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

У round своя странность: «ровно половина» округляется вверх, а не «от нуля». Из-за этого −1.5 становится −1, хотя 1.5 становится 2.

Числоroundfloorceiltrunc
1.52121
-1.4-1-2-1-1
-1.5-1-2-1-1
-1.6-2-2-1-1

floor — «ниже по прямой», trunc — «отрезать хвост». Для 1.2 это одно и то же, для -1.2 — уже нет.

Math.random() возвращает дробное число от 0 включительно до 1 не включительно. Аргументов у него нет, диапазон не настраивается — всё остальное вы считаете сами.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Чтобы получить целое от min до max включительно, растягиваем отрезок на нужную длину и отсекаем дробь через floor. Ширина диапазона — max - min + 1: единица добавлена ровно затем, чтобы верхняя граница тоже могла выпасть.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

С round диапазон вроде бы тот же, но крайние значения выпадают вдвое реже: к ним ведёт половинка отрезка, а к серединным — целый отрезок. Проверим на трёх числах.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Оба метода принимают сколько угодно аргументов — но именно аргументов, а не массив. Массив разворачивают спредом ....

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Последняя строка — не шутка, а ловушка: без аргументов Math.max возвращает -Infinity, а Math.min — Infinity. Значит, пустой массив в спреде тихо превратится в бесконечность. И любой NaN среди аргументов делает результат NaN целиком.

Самая частая пара — «зажать значение в границах»: наружный min держит потолок, внутренний max — пол.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Math.pow(a, b) возводит a в степень b, и у него есть более короткий синоним — оператор **. Math.sqrt берёт квадратный корень, Math.abs снимает знак.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Степень не обязана быть целой и положительной: дробная даёт корень, отрицательная — деление. Для кубического корня есть отдельный Math.cbrt, он точнее.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Math.hypot считает корень из суммы квадратов всех аргументов — ту самую гипотенузу из школы. Это готовая формула расстояния: разница по X, разница по Y, и вот вам длина отрезка.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Ручной вариант короче не становится, зато ломается на больших числах: квадрат может не поместиться в число и стать бесконечностью. Math.hypot внутри масштабирует значения и такой аварии избегает.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

  • Math — обычный объект с готовыми функциями: без new, всё вызывается как Math.что-то().
  • floor и ceil двигают число по числовой прямой, trunc — к нулю; на отрицательных floor и trunc расходятся, а round при ровной половине идёт вверх (-1.5 даёт -1).
  • Math.random() возвращает дробь от 0 до 1 не включительно; целое в диапазоне — Math.floor(Math.random() * (max - min + 1)) + min.
  • Math.min и Math.max берут аргументы, а не массив: разворачивайте спредом и помните про -Infinity у пустого вызова.
  • pow (или **), sqrt, abs решают школьную арифметику, а Math.hypot(a, b) сразу даёт расстояние и не переполняется на больших числах.

1/3Что выведет Math.floor(-1.5)?

2/3Чему равен Math.max() без единого аргумента?

3/3Какое выражение даёт случайное целое от 1 до 6 включительно, причём все шесть значений равновероятны?

Случайное целое в диапазоне

Напишите функцию randomInt(min, max), которая возвращает случайное целое число от min до max включительно — обе границы должны иногда выпадать.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Ширина диапазона — max - min + 1: единица нужна, чтобы верхняя граница тоже попадала в выборку. Растягиваем Math.random() на эту ширину, срезаем дробь через Math.floor и сдвигаем на min.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Именно floor, а не round: с округлением к ближайшему крайние значения выпадали бы вдвое реже остальных.

Самое далёкое от нуля

Дан массив чисел. Верните тот элемент, который дальше всех от нуля, — со своим знаком. Для [3, -12, 7, -5] ответ -12.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Расстояние до нуля — это модуль. Считаем максимальный модуль по всему массиву, а потом ищем первый элемент с таким модулем, чтобы вернуть его вместе со знаком.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Math.max не принимает массив, поэтому нужен спред. Передавать Math.abs прямо в map безопасно: лишние аргументы (индекс и массив) он просто игнорирует.