Number

Number — тип данных для представления целых и дробных чисел в формате IEEE 754 (64-bit double precision).

Зачем нужно

Числа нужны для математики, подсчётов, индексов, координат, таймеров и любых вычислений. Понимание особенностей чисел в JS предотвращает баги с точностью.

Где используется

  • Математические вычисления
  • Работа с индексами массивов
  • Таймеры и анимации
  • Финансовые расчёты (осторожно!)
  • Работа с API (пагинация, ID)

Предпосылки

Типы данных

Создание чисел

// Литералы
const integer = 42;
const float = 3.14;
const negative = -17;
const scientific = 2.5e6;   // 2 500 000
const small = 1.5e-3;       // 0.0015

// Разные системы счисления
const hex = 0xFF;           // 255 (шестнадцатеричная)
const octal = 0o77;         // 63 (восьмеричная)
const binary = 0b1010;      // 10 (двоичная)

// Разделитель разрядов (ES2021)
const billion = 1_000_000_000;
const bytes = 0xFF_FF_FF;

// Функция Number
console.log(Number('42'));      // 42
console.log(Number('3.14'));    // 3.14
console.log(Number(''));        // 0
console.log(Number(true));      // 1
console.log(Number(false));     // 0
console.log(Number(null));      // 0
console.log(Number(undefined)); // NaN
console.log(Number('hello'));   // NaN

Специальные значения

NaN (Not a Number)

console.log(typeof NaN);       // "number" — ирония!
console.log(NaN === NaN);      // false — единственное значение, не равное себе
console.log(NaN + 5);          // NaN — заразно

// Проверка
console.log(Number.isNaN(NaN));       // true
console.log(Number.isNaN('hello'));   // false (isNaN('hello') вернул бы true)
console.log(Object.is(NaN, NaN));    // true

Infinity

console.log(1 / 0);            // Infinity
console.log(-1 / 0);           // -Infinity
console.log(Infinity + 1);     // Infinity
console.log(Infinity - Infinity); // NaN

console.log(Number.isFinite(42));       // true
console.log(Number.isFinite(Infinity)); // false

Пределы точности

console.log(Number.MAX_SAFE_INTEGER);  // 9007199254740991 (2^53 - 1)
console.log(Number.MIN_SAFE_INTEGER);  // -9007199254740991

// За пределами безопасного диапазона
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992 — потеря точности!

console.log(Number.isSafeInteger(42));                  // true
console.log(Number.isSafeInteger(9007199254740992));   // false

Проблема точности с дробями

// IEEE 754 не может точно представить некоторые дроби
console.log(0.1 + 0.2);        // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false!

// Решения
// 1. Округление
console.log(+(0.1 + 0.2).toFixed(2)); // 0.3

// 2. Epsilon-сравнение
function areEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}
console.log(areEqual(0.1 + 0.2, 0.3)); // true

// 3. Работа в целых числах (копейки вместо рублей)
const priceInCents = 1999; // 19.99 руб
const total = priceInCents * 3; // 5997
console.log(total / 100); // 59.97 — точно!

Методы Number

const num = 42.5678;

// Преобразование в строку
num.toString();     // "42.5678"
num.toString(2);    // "101010.1001..." (двоичная)
num.toString(16);   // "2a.9..." (шестнадцатеричная)

// Форматирование
num.toFixed(2);     // "42.57" (строка! не число)
num.toPrecision(4); // "42.57" (4 значащих цифры)
num.toExponential(2); // "4.26e+1"

// Статические методы
Number.parseInt('42px');     // 42
Number.parseFloat('3.14m'); // 3.14
Number.isInteger(42);       // true
Number.isInteger(42.0);     // true
Number.isInteger(42.5);     // false
Number.isNaN(NaN);          // true
Number.isFinite(42);        // true

Объект Math

// Константы
Math.PI;     // 3.141592653589793
Math.E;      // 2.718281828459045
Math.LN2;    // 0.6931471805599453

// Округление
Math.round(4.5);   // 5 (ближайшее целое)
Math.round(4.4);   // 4
Math.ceil(4.1);    // 5 (вверх)
Math.floor(4.9);   // 4 (вниз)
Math.trunc(4.9);   // 4 (отбросить дробь)
Math.trunc(-4.9);  // -4

// Мин/Макс
Math.max(1, 5, 3);    // 5
Math.min(1, 5, 3);    // 1
Math.max(...[1,5,3]); // 5 (с массивом)

// Степень и корень
Math.pow(2, 10);  // 1024 (или 2 ** 10)
Math.sqrt(16);    // 4
Math.cbrt(27);    // 3
Math.hypot(3, 4); // 5 (гипотенуза)

// Модуль
Math.abs(-42);    // 42

// Логарифмы
Math.log(Math.E);   // 1
Math.log2(8);       // 3
Math.log10(1000);   // 3

// Тригонометрия
Math.sin(Math.PI / 2); // 1
Math.cos(0);            // 1
Math.atan2(1, 1);       // 0.785... (PI/4)

// Случайные числа
Math.random;                              // [0, 1)
Math.floor(Math.random * 10);            // 0-9
Math.floor(Math.random * (max - min + 1)) + min; // min-max

// Удобная функция
function randomInt(min, max) {
  return Math.floor(Math.random * (max - min + 1)) + min;
}
console.log(randomInt(1, 6)); // бросок кубика

Парсинг строк в числа

// parseInt — целые числа
parseInt('42');        // 42
parseInt('42px');      // 42 (игнорирует остаток)
parseInt('px42');      // NaN (начинается не с цифры)
parseInt('0xFF', 16);  // 255
parseInt('111', 2);    // 7 (двоичная)

// parseFloat — дробные числа
parseFloat('3.14');     // 3.14
parseFloat('3.14.15');  // 3.14 (до второй точки)

// Унарный + (самый краткий способ)
+'42';       // 42
+'3.14';     // 3.14
+'';         // 0
+true;       // 1
+null;       // 0
+undefined;  // NaN
+'hello';    // NaN

// Number — строже parseInt
Number('42px'); // NaN (parseInt вернул бы 42)
Number('');     // 0

Частые ошибки

1. toFixed возвращает строку

const price = 19.999;
const fixed = price.toFixed(2); // "20.00" — строка!
const num = +price.toFixed(2);  // 20 — число

2. Сравнение дробей

// Никогда не сравнивай дроби напрямую
if (0.1 + 0.2 === 0.3) { /* не выполнится */ }

// Используй epsilon или округление
if (Math.abs((0.1 + 0.2) - 0.3) < 1e-9) { /* OK */ }

3. parseInt без указания системы счисления

// Всегда указывай radix
parseInt('08');     // 8 (сейчас OK, раньше было 0 в старых движках)
parseInt('08', 10); // 8 (явно и надёжно)

Практика

  1. Напиши функцию randomInt(min, max) — случайное целое число в диапазоне
  2. Напиши функцию formatPrice(cents) — из копеек в "1 234.56 ₽"
  3. Проверь, является ли строка валидным числом (не NaN, не Infinity)
  4. Конвертируй температуру из Цельсия в Фаренгейт и обратно с точностью 2 знака

Связанные темы

Ресурсы


⚡ Источник: Effective JavaScript Code Optimization Techniques Numbers · AsForJS

  • 📅 2021-11-16 · YouTube
  • Тезисы:
    • V8 хранит числа в 2 форматах: SMI (Small Integer, 31 бит, untagged) и HeapNumber (полноценный IEEE 754, в куче)
    • Операции с SMI на порядок быстрее: нет аллокации, всё в регистрах
    • Деление 5/2 даёт HeapNumber (2.5), даже если потом приводится к int
    • Использование | 0 или Math.trunc для удержания числа в SMI — оптимизация

⚡ Источник: ⎡04⎦ JavaScript Performance and Data Types Numbers · AsForJS

  • 📅 2023-06-21 · YouTube
  • Тезисы: разница между Number Type (по спеке — IEEE 754) и его представлением в V8 (SMI/HeapNumber). Когда typeof x === 'number' — внутри может быть любой из вариантов

⚡ Источник: Почему NaN это диапазон из 9 квадриллионов чисел · AsForJS

  • 📅 2025-09-12 · YouTube
  • Тезисы:
    • В IEEE 754 NaN — это не одно значение, а диапазон: любое число с exponent=11111111111 и mantissa≠0
    • Это ~9 квадриллионов разных битовых представлений, все они typeof === 'number' и все NaN !== NaN
    • V8 использует NaN-boxing: некоторые NaN-представления используются для тегирования non-number значений в pointer

⚡ Источник: Производительность Math.trunc vs Or · AsForJS

  • 📅 2026-05-17 · YouTube
  • Тезисы: x | 0 быстрее Math.trunc(x) в V8 потому что | это bitwise, всегда возвращает int32, без вызова метода. Но работает только для чисел до 2^31

⚡ Источник: Решение задачи numberWithSpaces · AsForJS

  • 📅 2024-04-16 · YouTube
  • Тезисы: форматирование числа разделителями: Intl.NumberFormat, toLocaleString, или ручная regex /\B(?=(\d{3})+(?!\d))/g. Сравнение производительности

🎓 Источник: Typed Arrays in JavaScript

  • 📅 2018-12-06 · YouTube
  • Тезисы: Int8Array, Uint32Array, Float64Array и т.д. — массивы фиксированного типа над ArrayBuffer. Нужны для бинарных данных, WebGL, аудио, WASM. Не имеют holes