Числа и Math в JavaScript

Числа и Math в JavaScript #

Число в JavaScript — значение типа number: целые, дробные, NaN и бесконечности хранятся в одном типе по стандарту IEEE 754 (64-битное с плавающей точкой). Для цен, скидок, ETA доставки и игровых очков этого достаточно; для очень больших целых есть отдельный тип bigint.


Литералы и базовые операции #

const itemPrice = 490
const quantity = 3
const lineTotal = itemPrice * quantity // 1470

const discountRate = 0.15
const discounted = lineTotal * (1 - discountRate) // 1249.5

const hexColor = 0xff6600 // 16737792 — шестнадцатеричная запись
const binaryFlag = 0b1010 // 10

Деление всегда даёт число с плавающей точкой:

10 / 4 // 2.5
7 / 2 // 3.5

Остаток от деления — оператор %:

const minutes = 73
const hours = Math.floor(minutes / 60) // 1
const rest = minutes % 60 // 13 — «осталось 13 минут»

NaN, Infinity и проверки #

NaN («Not a Number») появляется, когда арифметика не может дать осмысленный результат:

Number('checkout') // NaN
0 / 0 // NaN

NaN не равен сам себе — сравнивайте через Number.isNaN:

NaN === NaN // false
Number.isNaN(NaN) // true
Number.isNaN('x') // false — не приводит аргумент

Infinity и -Infinity — результат переполнения или деления на ноль:

1 / 0 // Infinity
-1 / 0 // -Infinity

Для «нормальных» конечных чисел удобен Number.isFinite:

Number.isFinite(42) // true
Number.isFinite(Infinity) // false
Number.isFinite('42') // false — строка не число

Точность и округление #

Двоичное представление не всегда точно для десятичных дробей:

0.1 + 0.2 // 0.30000000000000004

В интерфейсе корзины показывайте сумму через форматирование, а не «сырое» сложение:

const subtotal = 0.1 + 0.2
subtotal.toFixed(2) // "0.30" — строка для отображения

const displayTotal = Math.round(subtotal * 100) / 100 // 0.3 — число

toFixed(n) возвращает строку с n знаками после запятой:

(1490.5).toFixed(0) // "1491"
(12.345).toFixed(2) // "12.35"

Math.round, Math.floor, Math.ceil, Math.trunc — разные стратегии округления:

const deliveryFee = 89.7

Math.round(deliveryFee) // 90
Math.floor(deliveryFee) // 89
Math.ceil(deliveryFee) // 90
Math.trunc(-3.9) // -3

parseInt, parseFloat и Number #

Строки из форм и API часто нужно превратить в число:

parseInt('150₽', 10) // 150 — читает с начала, основание 10 обязательно
parseFloat('3.14 кг') // 3.14
Number('  42  ') // 42 — вся строка должна быть числом
Number('42px') // NaN

Унарный + — краткий аналог Number:

const rawQty = '2'
const qty = +rawQty // 2

Для пользовательского ввода надёжнее явная функция с запасным значением:

function toCartQuantity(value, fallback = 1) {
  const n = Number(value)
  if (!Number.isInteger(n) || n < 1) return fallback
  return n
}

toCartQuantity('3') // 3
toCartQuantity('0') // 1
toCartQuantity('abc') // 1

Объект Math #

Math — встроенный набор математических функций и констант (не конструктор):

Math.PI // 3.141592653589793
Math.abs(-17) // 17
Math.max(10, 3, 88) // 88
Math.min(...[490, 320, 150]) // 150

Math.pow(2, 10) // 1024 — то же, что 2 ** 10
Math.sqrt(144) // 12

Случайное число в диапазоне [min, max):

function randomScore(min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

randomScore(1, 101) // целое от 1 до 100 включительно при max = 101

Округление до шага (например, скидка кратно 50 ₽):

function roundToStep(amount, step) {
  return Math.round(amount / step) * step
}

roundToStep(1249, 50) // 1250

BigInt #

Если целое не помещается в безопасный диапазон Number (Number.MAX_SAFE_INTEGER9007199254740991), используйте bigint с суффиксом n:

const bigOrderId = 9007199254740992n
bigOrderId + 1n // 9007199254740993n

// bigOrderId + 1 — TypeError: нельзя смешивать bigint и number

BigInt не подходит для дробей и не смешивается с number в одной операции без явного приведения.


Сравнение и особые значения #

const scoreA = 100
const scoreB = '100'

scoreA == scoreB // true — неявное приведение
scoreA === scoreB // false — разные типы

Object.is(0, -0) // false
Object.is(NaN, NaN) // true — в отличие от ===

Для денег и количества в коде предпочитайте === и заранее нормализованные числа (см. Преобразование типов).


Практика: итог корзины #

const cartLines = [
  { sku: 'kb-01', price: 490, qty: 1 },
  { sku: 'ms-02', price: 1290, qty: 2 },
]

function cartSubtotal(lines) {
  return lines.reduce((sum, line) => sum + line.price * line.qty, 0)
}

function applyDeliveryFee(subtotal, freeFrom = 3000, fee = 199) {
  return subtotal >= freeFrom ? 0 : fee
}

const subtotal = cartSubtotal(cartLines) // 3070
const delivery = applyDeliveryFee(subtotal)
const total = subtotal + delivery

`${total.toFixed(2)} ₽` // "3269.00 ₽" при fee = 199

Итог #

  • В JS один числовой тип number (плюс bigint для огромных целых).
  • NaN и Infinity — особые значения; проверяйте через Number.isNaN и Number.isFinite.
  • Дробная арифметика может давать артефакты — форматируйте вывод через toFixed или целые копейки.
  • parseInt/parseFloat терпимы к «хвосту» в строке; Number — строже.
  • Math даёт округление, min/max, степени и псевдослучайность без подключения библиотек.

См. также #