Работа с числами и математическими методами в JavaScript
Подборка самых важных и часто используемых методов работы с числами и математическими функциями в JavaScript с примерами.
Вам будет проще разобраться с этими методами, если вы уже знакомы с типами данных в JavaScript.
Основы работы с числами
- В JavaScript существует всего один числовой тип. Таким образом, значения
5
и5.12
принадлежат к одному и тому же типу. - JS использует формат 64-битных чисел двойной точности по стандарту IEEE 754.
Это означает, что все числа в JavaScript имеют плавающую запятую. Пусть вас не обманывает запись var x = 1
, на самом деле это float, равный 1.0
.
Если вы действительно хотите разобраться в особенностях чисел в JS, загляните сюда:
- ECMAScript® 2018 Language Specification. Number Type
- Here is what you need to know about JavaScript’s Number type
А в этой статье мы сконцентрируемся на методах работы со значениями типа Number.
Создание чисел
Объявить переменную, содержащую числовое значение, можно с помощью ключевых слов let (если она будет изменяться) или const (если не будет). Перед отрицательными числами ставится -
:
const PI = 3.14 const x = 1 const n = -10
Единственный 0 в целой или дробной части числа можно не указывать, но все же стоит это делать для лучшей читаемости кода.
const y = 0.15 const z = .90 const t = 5.
Будьте осторожны с ограничениями по размеру:
const r = 9999999999999999 // 10000000000000000 const l = 999999999999999999999999 // 1e+25 const i = Infinity // Infinity - бесконечность со знаком +
Конвертация в число:
const str = '24.23' const bin = '110110' const short = +str // 24.23 const num = Number(str) // 24.23 // второй аргумент – основание системы счисления const b = Number.parseInt(bin, 2) // 54
Можно работать и в других системах счисления:
const hex = 0xff // 255 const octal = 012 // 10 const betterOctal = 0o23 // 19 - способ работы с восьмеричной системой, введенный в ES6 const binary = 0b1101 // 13
Важные принципы
- все числа – с плавающей точкой;
- все числа имеют один тип - "number";
- как и в других языках, в JS существуют ограничения по максимальному размеру и точности чисел.
Основные методы
Безопасные числа
Скорее всего, вы хотите, чтобы значение числа всегда оставалось тем же самым, что вы ему задали. Но если вы используете в коде, к примеру, число 900719925474099164 оно превратится в 900719925474099200. Дело в том, что оно выходит за пределы так называемого безопасного диапазона.
Узнать эти пределы можно, обратившись к свойствам объекта Number MIN_SAFE_INTEGER и MAX_SAFE_INTEGER. А с помощью функции Number.isSafeInteger можно определить, является ли число безопасным.
// константы минимального и максимального безопасных чисел Number.MAX_SAFE_INTEGER // 9007199254740991 Number.MIN_SAFE_INTEGER // -9007199254740991 // не путайте их с минимальным и максимальным числом Number.MAX_VALUE // 1.7976931348623157e+308 Number.MIN_VALUE // 5e-324 // проверка, находится ли число в безопасном диапазоне Number.isSafeInteger(1.7976931348623157e+308) // false Number.isSafeInteger(9007199254740991) // true
Целое ли число?
Используйте метод isInteger
объекта Number
. Если число не имеет десятичной части, он возвращает true
. Обратите внимание, что числа с пустой десятичной частью автоматически конвертируются в целые.
Number.isInteger(5) // true Number.isInteger(5 / 2) // false Number.isInteger(5.00) // true
Есть более короткий, но менее читаемый способ проверить, целое ли число:
5 % 1 === 0 // true 5.5 % 1 === 0 // false
Изменение количества знаков после запятой
Используйте метод Number.toFixed
, который принимает количество знаков десятичной части, а возвращает строковое представление числа в нужном формате.
const a = 5.6710142 const b = 0.993 a.toFixed(2) // '5.67' a.toFixed(1) // '5.7' b.toFixed() // '1' b.toFixed(20) // '0.99299999999999999378' b.toFixed(30) // некоторые браузеры не поддерживают более 20 символов
Также можно воспользоваться методом Number.toPrecision
, которому нужно передать количество значащих цифр числа. На выходе также получается строка:
const a = 5.6710142 const b = 0.993 a.toPrecision(2) // '5.7' a.toPrecision(1) // '6' b.toPrecision() // 0.993 b.toPrecision(20) // 0.99299999999999999378
Преобразование в экспоненциальную форму
Экспоненциальная форма известна также известна как научная нотация. Для преобразования существует специальный метод toExponential
. Его единственный необязательный параметр – количество цифр после запятой.
const x = 25893210 const y = 33.1894 const z = 10000000 const p = x.toExponential() // '2.589321e+7' y.toExponential() // '3.31894e+1' z.toExponential() // '1e+7' z.toExponential(2) // '1.00e+7' // обратное преобразование console.log(p) // '2.589321e+7' Number(p) // 25893210 parseFloat(p) // 25893210
Глобальные функции для работы с числами и методы Number
Вы, возможно, знаете, что существуют глобальные функции вроде parseInt
, но только что мы использовали Number.parseInt()
.
Дело в том, что последний стандарт JavaScript пытается модуляризировать глобальные сущности и обновляет некоторые существующие модули. Например, метод isNaN
отличается от нового метода Number.isNaN
.
Работа с большими числами
Тип BigInt на данный момент находится в статусе предложения и недоступен в ряде браузеров. Большие числа создаются путем добавления n
в конец числа или с помощью конструктора.
const large = 9007199254740991n const constructed = BigInt(9007199254740991) // 9007199254740991n const fromString = BigInt('9007199254740991') // 9007199254740991n const safe = BigInt(Number.MAX_SAFE_INTEGER) // 9007199254740991n safe + 3n // 9007199254740994n large + safe // 18014398509481982n
Пока нет полной поддержки BigInt, вы можете использовать библиотеку bignumber.js.
Преобразование в другую систему счисления
Перевести число из десятичной системы в другую можно с помощью метода toString
, указав желаемое основание системы (от 2 до 36). Для обратного преобразования используйте метод parseInt
:
const num = 3241 const bin = num.toString(2) // '110010101001' num.toString(8) // '6251' num.toString(16) // 'ca9' num.toString(10) // '3241' Number.parseInt(bin, 2) // 3241
Методы числовых литералов
Возможно, вы попытались применить какой-нибудь метод к числовому литералу (23.toString(2)
) и получили синтаксическую ошибку. Это связано со специфическим представлением чисел в JavaScript. Валидная форма для числа 23 - 23.
или 23.0
(0 в дробной части можно не указывать).
Когда вы пишете 23.toString(2)
JavaScript считает эту запись числом и не понимает, что вызывается метод.
Решением может быть использование скобок или двух точек для указания дробной части (хотя это довольно непонятная запись):
(23).toString(2) // "10111" 23..toString(2)
Не число – это число
Подробное объяснение этого феномена можно найти в статье JS Essentials: Types & Data Structures.
Коротко говоря, NaN
является объектом класса Number, но определяется как результат математических операций, значение которых количественно число не является. Правильнее было бы назвать его Invalid Number.
NaN
превращает все, с чем имеет дело, в NaN
.
const a = 5 + NaN // NaN
Проверка на NaN
Это единственное значение в JavaScript, которое не равно самому себе. Мы можем использовать это, применяя проверку x !== x
. Если это условие возвращает true
, то x – это NaN
.
Помимо этого можно использовать методы Object.is
, isNaN
и новый метод Number.isNaN
. Обратите внимание, два последних метода ведут себя по-разному с нечисловыми значениями.
NaN == NaN // false NaN === NaN // false Object.is(NaN, NaN) // true isNaN(NaN) // true isNaN('abc') // true Number.isNaN(NaN) // true Number.isNaN('abc') // false Number.isNaN(+'abc') // true
Способы округления чисел
const x = 5.921 // округление вниз Math.floor(x) // 5 // округление вверх Math.ceil(x) // 6 // округление по правилам математики Math.round(x) // 6 Math.round(5.5) // 6 // до нужного количества цифр после точки x.toFixed(2) // 5.92 x.toPrecision(2) // 5.9 // битовый сдвиг // работает быстрее, чем Math.floor // но очень неочевидно для ваших коллег x >> 0 // 5
Возведение в степень
В JavaScript существует специальный оператор степени – **
. Также можно воспользоваться методом Math.pow
.
2 ** 2 // 4 let x = 2 x ** = 4 // 16 Math.pow(2, 4) // 16
Генерация случайного числа
Метод Math.random
генерирует дробное число в диапазоне от 0 (включая) до 1 (не включая).
Math.random() // 0.7610368478059286 // генерация числа в диапазоне от 0 до 9 // битовый сдвиг работает как Math.floor Math.random() * 10 >> 0 Math.floor(Math.random() * 10) // генерация числа в диапазоне [x, y) const getRandom = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
Вот небольшой пример: создадим сет – набор уникальных значений, заполним его случайными числами с помощью метода getRandom
и отсортируем:
for (let i of Array(500)) { values.add(getRandom(1, 10)) } [...values].sort((a, b) => a - b) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Математические функции
В модуле Math
очень много полезных методов, которые вы можете найти в документации. Все они имеют довольно очевидный принцип работы.
Полезные ссылки
- JavaScript Essentials – серия простых и полезных статей об основных методах и приемах работы в Javascript.
- Спецификация ECMAScript 2018.
- Документация по объекту Number.
- Документация по модулю Math.
Практика работы с числами
Несколько полезных челленджей на codewars.com.
Перевод статьи JavaScript Essentials: Numbers and Math.