Тип данных Number. Его особенности, свойства, методы.
Все числа в JavaScript, как целые так и дробные, имеют тип Number и хранятся в 64-битном формате.
Способы записи
В JavaScript можно записывать числа не только в десятичной, но и в шестнадцатеричной (начинается с 0x) системе счисления:
alert( 0xFF ); // 255 в шестнадцатиричной системе
Экспоненциальное представление, которое выглядит как <число>e<количество нулей>:
alert( 3e5 ); // 300000
Если количество нулей отрицательно, то число сдвигается вправо за десятичную точку, так что получается десятичная дробь:
alert( 3e-5 ); // 0.00003
Деление на ноль, Infinity
alert( 1 / 0 ); // Infinity
Infinity – особенное численное значение, которое ведет себя в точности как математическая бесконечность. Infinity больше любого числа. Добавление к бесконечности не меняет её:
alert( Infinity + 5 == Infinity ); // true
Бывает и минус бесконечность -Infinity:
alert( -1 / 0 ); // -Infinity
Бесконечность можно получить также, если сделать очень большое число, для которого количество разрядов в двоичном представлении не помещается в соответствующую часть стандартного 64-битного формата, например:
alert( 1e500 ); // Infinity
NaN
Если математическая операция не может быть совершена, то возвращается специальное значение NaN (Not-A-Number). Например, деление 0/0 в математическом смысле неопределено, поэтому его результат NaN:
alert( 0 / 0 ); // NaN
Значение NaN используется для обозначения математической ошибки и обладает следующими свойствами:
ü Значение NaN – единственное в своем роде, которое не равно ничему, включая себя.
NaN === NaN // false
ü Значение NaN можно проверить специальной функцией isNaN(n), которая преобразует аргумент к числу и возвращает true, если получилось NaN, и false – для любого другого значения. Если аргумент isNaN – не число, то он автоматически преобразуется к числу.
isNaN(NaN); // true
isNaN("12"); // false, строка преобразовалась к обычному числу 12
isFinite(n)
Функция isFinite(n) преобразует аргумент к числу и возвращает true, если это не NaN/Infinity/-Infinity:
isFinite(1); // true
isFinite(Infinity); // false
isFinite(NaN); // false
Преобразование к числу
Большинство арифметических операций и математических функций преобразуют значение в число автоматически. Для того чтобы сделать это явно, обычно перед значением ставят унарный плюс '+':
alert( +"12.34" ); // 12.34
При этом, если строка не является в точности числом, то результат будет NaN:
alert( +"12test" ); // NaN
Number — конструктор числа.
Number(12); // 12
Number('12.34'); // 12.34
Number('12text'); // NaN
Мягкое преобразование: parseInt и parseFloat
В мире HTML/CSS многие значения не являются в точности числами. Например метрики CSS: 10pt или -12px. Для удобного чтения таких значений существует функция parseInt:
parseInt('12px'); // 12
Функция parseInt и ее аналог parseFloat преобразуют строку символ за символом, пока это возможно. При возникновении ошибки возвращается число, которое получилось. Функция parseInt читает из строки целое число, а parseFloat – дробное. Конечно, существуют ситуации, когда parseInt/parseFloat возвращают NaN. Это происходит при ошибке на первом же символе:
parseInt('a123'); // NaN
Функция parseInt также позволяет указать систему счисления, то есть считывать числа, заданные в шестнадцатиричной и других системах счисления:
parseInt('FF', 16); // 255
toPrecision(precision)
— приведение к десятичной форме (precision — число значащих цифр, 1..21)
(123.456789).toPrecision(2); // '1.2e+2'
(123.456789).toPrecision(4); // '123.5
(123.456789).toPrecision(); // '123.456789'
toExponential(fractionDigits)
— приведение к экспоненциальной форме (fractionDigits — количество знаков после запятой, 0..20)
(123.456789).toExponential(0); // 1e+2
(123.456789).toExponential(2); // 1.23e+2
(123.456789).toExponential(5); // 1.23457e+2
toString(radix)
— преобразует число в строку (radix — основание системы счисления, 2..36 (по-умолчанию — 10))
(123.456789).toString(8); // '173.3517003756026054'
(123.456789).toString(16); // '7b.74f01fb82c2c'
Округление
Одна из самых частых операций с числом – округление. В JavaScript существуют целых 3 функции для этого:
Math.floor - округляет вниз
Math.ceil - округляет вверх
Math.round - округляет до ближайшего целого
Math.floor(3.1); // 3
Math.ceil(3.1); // 4
Math.round(3.1); // 3
toFixed(precision)
Существует также специальный метод toFixed(precision), который округляет число до точности precision и возвращает результат в виде строки (округление идёт до ближайшего значения):
(12.34).toFixed(1); // "12.3"
Итоговая строка, при необходимости, дополняется нулями до нужной точности:
(12.34).toFixed(5) ); // "12.34000"
Неточные вычисления
(0.1 + 0.2) == 0.3 // false
(0.1 + 0.2); // 0.30000000000000004
(0.1 + 0.2 > 0.3); // true
Всё дело в том, что на число выделяется ровно 8 байт (=64 бита), не больше и не меньше.
Число 0.1 (одна десятая) записывается просто в десятичном формате. Но в двоичной системе счисления это бесконечная дробь, так как единица на десять в двоичной системе так просто не делится. Двоичное значение бесконечных дробей хранится только до определенного знака, поэтому возникает неточность. Её даже можно увидеть:
(0.1).toFixed(20); // 0.10000000000000000555
Когда мы складываем 0.1 и 0.2, то две неточности складываются, получаем незначительную, но всё же ошибку в вычислениях. Конечно, это не означает, что точные вычисления для таких чисел невозможны. Например, есть два способа сложить 0.1 и 0.2:
ü Сделать их целыми, сложить, а потом поделить:
(0.1 * 10 + 0.2 * 10) / 10; // 0.3
ü Сложить, а затем округлить до разумного знака после запятой. Округления до 10-го знака обычно бывает достаточно, чтобы отсечь ошибку вычислений.
Из 64 бит, отведённых на число, сами цифры числа занимают до 52 бит, остальные 11 бит хранят позицию десятичной точки и один бит – знак. Так что если 52 бит не хватает на цифры, то при записи пропадут младшие разряды.
Другие математические методы
JavaScript предоставляет базовые тригонометрические и некоторые другие функции для работы с числами.
Встроенные функции для тригонометрических вычислений:
Math.acos(x) - возвращает арккосинус x (в радианах)
Math.asin(x) - возвращает арксинус x (в радианах)
Math.atan(x) - возвращает арктангенс x (в радианах)
Math.sin(x) - вычисляет синус x
Math.cos(x) - вычисляет косинус x
Math.tan(x) - возвращает тангенс x
Разные полезные функции:
Math.sqrt(x) - возвращает квадратный корень из x
Math.log(x) - возвращает натуральный (по основанию e) логарифм x
Math.pow(x, exp) - возводит число в степень
Math.abs(x) - возвращает абсолютное значение числа
Math.max(a, b, c...) - возвращает наибольший из списка аргументов
Math.min(a, b, c...) - возвращает наименьший из списка аргументов