Минимум, максимум и округление

Минимум, максимум и округление

Технический фундамент границ и округления

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

  • ограничить значение диапазоном (min/max);
  • выбрать сторону округления (floor/ceil) по требованиям задачи;
  • отделить «математическое округление» (round) от «просто отбросить дробь» (trunc).

Инженерный принцип: сначала фиксируй правило результата, потом подбирай метод Math.

Почему эта тема важнее, чем кажется

Math.min, Math.max и методы округления участвуют почти в каждом продукте: цена товара, проценты прогресса, рейтинг, количество страниц, лимиты, ограничения в формах. Если выбрать неправильный метод округления, ты можешь получить баг на уровне бизнес-логики, а не просто «косметическую неточность».

Поиск границ: Math.min и Math.max

console.log(Math.min(8, 3, 12)); // 3
console.log(Math.max(8, 3, 12)); // 12

Когда данные в массиве, добавляй spread:

const temperatures = [18, 23, 16, 29];
console.log(Math.min(...temperatures)); // 16
console.log(Math.max(...temperatures)); // 29

Ключевой момент: Math.max(temperatures) не работает как ожидается, потому что методу нужны отдельные аргументы, а не массив.

Проверь себя: что вернет Math.min() без аргументов?

Подсказка: Infinity. А Math.max() без аргументов вернет -Infinity.

Округление: round, floor, ceil, trunc

console.log(Math.round(4.5)); // 5
console.log(Math.floor(4.9)); // 4
console.log(Math.ceil(4.1)); // 5
console.log(Math.trunc(4.9)); // 4
  • round — до ближайшего целого;
  • floor — всегда вниз;
  • ceil — всегда вверх;
  • trunc — отрезает дробную часть.

На положительных числах floor и trunc часто совпадают, поэтому новичкам кажется, что это «одно и то же». Но на отрицательных числах разница критичная.

console.log(Math.floor(-2.3)); // -3
console.log(Math.trunc(-2.3)); // -2

Еще один нюанс: Math.round на значениях вида x.5 округляет в сторону +Infinity. На отрицательных числах это выглядит неожиданно:

console.log(Math.round(1.5)); // 2
console.log(Math.round(-1.5)); // -1

Что выбрать в реальной задаче

Смотри, что важно: метод выбирается по бизнес-правилу.

  • Для числа страниц обычно Math.ceil(total / size), потому что «хвост» тоже занимает страницу.
  • Для количества полных наборов — Math.floor.
  • Для отображения суммы «без копеек» может подойти trunc.
function getPageCount(totalItems, pageSize) {
  return Math.ceil(totalItems / pageSize);
}

Микро-сценарии

  1. Ограничение значения по диапазону (clamp).
function clamp(value, min, max) {
  return Math.min(Math.max(value, min), max);
}
  1. Нормализация рейтинга для UI.
function normalizeRating(value) {
  return Math.round(value * 10) / 10;
}

Смотри, что важно: из-за погрешностей дробей иногда удобно добавлять Number.EPSILON, чтобы стабилизировать округление:

function normalizeRatingSafe(value) {
  return Math.round((value + Number.EPSILON) * 10) / 10;
}
  1. Безопасное преобразование входа из строки и округление вверх.
function parseItemsCount(rawValue) {
  const value = Number(rawValue);
  if (!Number.isFinite(value) || value < 0) return 0;
  return Math.ceil(value);
}

Типичные ошибки

  • Использовать round, когда нужно всегда вверх (ceil).
  • Путать floor и trunc на отрицательных числах.
  • Передавать массив без spread в min/max.
  • Не учитывать Infinity/-Infinity в крайних сценариях.

Анти-провал: перед выбором метода округления спроси себя: «мне нужно математически ближайшее число или строго вверх/вниз?»

Краткий итог

  • min/max помогают работать с границами значений.
  • Методы округления решают разные задачи, они не взаимозаменяемы.
  • Для массивов в min/max нужен spread.
  • На отрицательных числах разница методов особенно заметна.
  • Точная логика округления напрямую влияет на корректность продукта.