JavaScript числа: целые и с плавающей точкой
- Целочисленные литералы
- Литералы с плавающей точкой
- Экспоненциальная запись числа
- Разделители в числовых литералах
- Infinity и NaN
- BigInt
Числовой тип данных (number) служит для представления целых чисел и чисел с плавающей точкой (десятичных дробей).
Для представления чисел в JavaScript используется 64-битный формат, определяемый стандартом IEEE-754. Этот формат способен представлять числа с плавающей точкой в диапазоне от ±5 · 10-324 до ±1.7976931348623157 · 10308, а все целые числа в диапазоне от −9 007 199 254 740 992 до 9 007 199 254 740 992 включительно. Из 64 бит 52 используются для хранения цифр, 11 бит — для хранения положения десятичной точки и оставшийся один бит — для знака числа.
Для записи чисел предусмотрено несколько разных форматов числовых литералов.
Целочисленные литералы
Самый простой способ записи целого числа — формат десятичных целочисленных литералов, в котором число записывается как последовательность цифр из десятичной системы счисления:
0
9
12345
Любому числовому литералу может предшествовать знак
(минус), делающий число отрицательным:−
-200 // Отрицательное целое число
Помимо десятичных целочисленных литералов JavaScript позволяет записывать целые числа в формате шестнадцатеричных литералов. Шестнадцатеричный литерал начинается с последовательности символов 0x или 0X (первый символ — цифра нуль, второй — латинская буква x
), за которой следует последовательность шестнадцатеричных цифр. Шестнадцатеричная цифра — это одна из цифр от 0 до 9 или одна из латинских букв от a (или A) до f (или F), которые представляют значения от 10 до 15. Например:
0xff // Целое число (255)
0XFF // Тоже самое
Также целые числа можно записывать в формате восьмеричного литерала. Восьмеричный литерал начинается с последовательности символов 0o или 0O (первый символ — цифра нуль, второй — латинская буква o
), за которой следует последовательность восьмеричных цифр. Восьмеричная цифра — это одна из цифр от 0 до 7. Например:
0o70 // Целое число (56)
0O70 // Тоже самое
И последний вариант записи целых чисел — запись в формате двоичного литерала. Двоичный литерал начинается с последовательности символов 0b или 0B (первый символ — цифра нуль, второй — латинская буква b
), за которой следует последовательность двоичных цифр. Двоичная цифра — это одна из цифр 0 или 1. Например:
0b110 // Целое число (6)
0B110 // Тоже самое
В каком бы формате не были записаны числа, все они выводятся в виде десятичного числа:
alert(0xff); // 255
Литералы с плавающей точкой
Чтобы использовать число с плавающей точкой, необходимо ввести десятичную точку и как минимум одну цифру после неё. Нуль перед десятичной точкой необязателен:
0.3 // Литерал числа с плавающей точкой
.3 // Тоже самое
Числа с плавающей точкой представляются с точностью до 16-го десятичного разряда включительно. Из-за этого например, сложение 0.1 и 0.2 даёт в результате 0.30000000000000004 вместо 0.3. Факт того, что число с плавающей точкой не может быть представлено точно, может приводить к проблемам при сравнении чисел после вычислений:
let x = 0.3 - 0.2;
let y = 0.2 - 0.1;
alert(x == y); // false
alert(x == 0.1); // false
alert(y == 0.1); // true
Важно понимать, что эта проблема не является чем-то характерным для JavaScript, она проявляется во всех языках программирования, где для представления чисел c плавающей точкой используется формат, определяемый стандартом IEEE-754. Точность чисел с плавающей точкой вполне приемлема, проблема может возникать лишь при проверке на равенство результатов вычислений, производимых с числами с плавающей точкой.
Так как для хранения чисел с плавающей точкой требуется вдвое больше памяти, чем для целых чисел, интерпретатор по возможности преобразует числа с плавающей точкой в целые числа. Если после десятичной точки ничего не указано, число преобразуется в целое. Если в дробной части числа стоит 0 (например, 12.0), оно преобразуется в целое:
alert(Number.isInteger(10.)); // true
alert(Number.isInteger(10.0)); // true
Экспоненциальная запись числа
Числа можно представлять в виде экспоненциальной записи. Экспоненциальная запись означает число, умноженное на 10 в указанной степени. Экспоненциальная запись состоит из числа, за которым следует прописная или строчная латинская буква e
, после которой можно поставить необязательный знак + или − и далее показатель степени числа 10:
alert(12e3); // 12000
alert(12e+3); // Тоже самое - 12000
alert(7E-3); // 0.007
По умолчанию интерпретатор переводит в экспоненциальную запись любые числа с плавающей точкой, содержащие как минимум шесть нулей после точки:
alert(0.0000005); // 5e-7
Для работы с числами в JavaScript существуют все базовые арифметические операции: умножение, деление, сложение и вычитание.
В дополнение к базовым арифметическим операциям JavaScript поддерживает более сложные математические действия через набор функций и констант, определённых как свойства объектов Math и Number.
Разделители в числовых литералах
В числовых литералах допускается использовать символ подчёркивания _
в качестве разделителя:
1_000_000_000
0x3A_FF_EC_AB
0b0101_1001_1100
0.112_133_543
Символ подчёркивания делает запись числа более читабельной. Интерпретатор JavaScript при анализе кода игнорирует символ подчёркивания между цифрами, поэтому он никак не влияет на программу.
Infinity и NaN
К числовому типу относятся также три специальных значения: Infinity, -Infinity и NaN.
Значение Infinity (положительная бесконечность) представляет собой математическую бесконечность. Это специальное значение, которое больше любого числа.
Значение Infinity можно получить:
- в результате деления числа на 0;
- когда результат выполнения математической операции не попадает в допустимый диапазон чисел JavaScript. Любое отрицательное число, которое превышает наибольшее представимое отрицательное значение, считается отрицательной бесконечностью (
-Infinity), а положительное – положительной бесконечностью (Infinity).
alert(123 / 0); // Infinity
alert(-12345 / 0); // -Infinity
alert(1e500); // Infinity
alert(1 - 1e500); // -Infinity
Сложение, вычитание, умножение или деление бесконечности на что угодно даёт в результате значение бесконечности (возможно с обратным знаком), а любое число, делённое на Infinity даёт 0:
alert(20 + Infinity); // Infinity
alert(Infinity/3); // Infinity
alert(32/Infinity); // 0
Значение NaN (Not a Number — не число) означает математическую ошибку, которая возникает в том случае, если математическая операция не может быть совершена.
Значение NaN можно получить:
- при делении нуля на нуль;
- при делении бесконечности на бесконечность;
- при взятии квадратного корня из отрицательного числа;
- применяя арифметические операции с нечисловыми операндами, которые не могут быть преобразованы в числа.
let a = 10, b = "текст";
alert(a - b); // NaN
alert(0 / 0); // NaN
Значение NaN обладает одной особенностью: оно не равно никакому другому значению, в том числе и другому NaN:
alert(NaN == NaN); // false
Чтобы определить, является ли значение переменной значением NaN следует выполнить проверку на неравенство x != x. Эта проверка вернёт true тогда и только тогда, когда x имеет значение NaN:
let x = NaN;
alert(x != x); // true
Любая арифметическая операция с NaN всегда возвращает NaN:
alert(NaN / 10); // NaN
Для хранения значений Infinity и NaN в JavaScript имеются предопределённые одноимённые свойства глобального объекта Infinity и NaN, значения которых также доступны в виде свойств объекта Number:
Infinity // Свойство глобального объекта
Number.POSITIVE_INFINITY // Свойство объекта Number
Number.NEGATIVE_INFINITY // Свойство объекта Number
NaN // Свойство глобального объекта
Number.NaN // Свойство объекта Number
BigInt
BigInt — это специальный числовой тип, который позволяет работать с целыми числами произвольной длины. Значения BigInt могут иметь любое количество цифр.
Литералы типа BigInt записываются как последовательность цифр, за которой следует латинская буква n в нижнем регистре. Помимо десятичной записи, значения BigInt можно записывать и в формате двоичных, восьмеричных и шестнадцатеричных литералов, используя те же префиксы: 0b, 0o и 0x:
1234567n // Десятичная запись
0b1110111n // Двоичная запись
0o7777777n // Восьмеричная запись
0x9000000000ABn // Шестнадцатеричная запись
Также для создания значений BigInt можно использовать функцию BigInt(), которая создаст число типа BigInt из переданного ей аргумента. Аргументом может быть число или строка:
let a = BigInt("123456789");
let b = BigInt(Number.MAX_SAFE_INTEGER);
Арифметические действия со значениями BigInt работают подобно арифметическим действиям с обыкновенными числами за исключением того, что операция деления отбрасывает любой остаток и округляет результат в меньшую сторону. Все операции с числами типа BigInt возвращают BigInt:
alert(5n + 2n); // 7n
alert(5n / 2n); // 2n
В арифметических операциях нельзя смешивать значения типа BigInt со значениями типа number:
alert(1n + 2); // Ошибка
К числам BigInt нельзя применять унарный оператор +:
alert(+1n); // Ошибка
Операции сравнения работают со смешанными числовыми типами:
alert(3n > 1n); // true
alert(3n > 1); // true
При сравнении чисел разных типов, они могут быть равны только при нестрогом сравнении ==:
alert(5n == 5); // true
alert(5n === 5); // false
Ни одна из функций объекта Math не работает с типом BigInt.