Math.floor()
Содержание:
瀏覽器相容性
The compatibility table in this page is generated from structured data. If you’d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
Update compatibility data on GitHub
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Chrome Full support 1 |
Edge Full support 12 |
Firefox Full support 1 |
IE Full support 3 |
Opera Full support 3 |
Safari Full support 1 |
WebView Android Full support 1 |
Chrome Android Full support 18 |
Firefox Android Full support 4 |
Opera Android Full support 10.1 |
Safari iOS Full support 1 |
Samsung Internet Android Full support 1.0 |
nodejs Full support 0.1.100 |
範例
使用
The following example shows example usage of .
Math.ceil(.95); // 1 Math.ceil(4); // 4 Math.ceil(7.004); // 8 Math.ceil(-0.95); // -0 Math.ceil(-4); // -4 Math.ceil(-7.004); // -7
Decimal adjustment
// Closure
(function() {
/**
* Decimal adjustment of a number.
*
* @param {String} type The type of adjustment.
* @param {Number} value The number.
* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
* @returns {Number} The adjusted value.
*/
function decimalAdjust(type, value, exp) {
// If the exp is undefined or zero...
if (typeof exp === 'undefined' || +exp === 0) {
return Math(value);
}
value = +value;
exp = +exp;
// If the value is not a number or the exp is not an integer...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// Shift
value = value.toString().split('e');
value = Math(+(value + 'e' + (value ? (+value - exp) : -exp)));
// Shift back
value = value.toString().split('e');
return +(value + 'e' + (value ? (+value + exp) : exp));
}
// Decimal round
if (!Math.round10) {
Math.round10 = function(value, exp) {
return decimalAdjust('round', value, exp);
};
}
// Decimal floor
if (!Math.floor10) {
Math.floor10 = function(value, exp) {
return decimalAdjust('floor', value, exp);
};
}
// Decimal ceil
if (!Math.ceil10) {
Math.ceil10 = function(value, exp) {
return decimalAdjust('ceil', value, exp);
};
}
})();
// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50
Примеры
Пример: корректировка округления десятичных дробей
// Замыкание
(function() {
/**
* Корректировка округления десятичных дробей.
*
* @param {String} type Тип корректировки.
* @param {Number} value Число.
* @param {Integer} exp Показатель степени (десятичный логарифм основания корректировки).
* @returns {Number} Скорректированное значение.
*/
function decimalAdjust(type, value, exp) {
// Если степень не определена, либо равна нулю...
if (typeof exp === 'undefined' || +exp === 0) {
return Math(value);
}
value = +value;
exp = +exp;
// Если значение не является числом, либо степень не является целым числом...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// Сдвиг разрядов
value = value.toString().split('e');
value = Math(+(value + 'e' + (value ? (+value - exp) : -exp)));
// Обратный сдвиг
value = value.toString().split('e');
return +(value + 'e' + (value ? (+value + exp) : exp));
}
// Десятичное округление к ближайшему
if (!Math.round10) {
Math.round10 = function(value, exp) {
return decimalAdjust('round', value, exp);
};
}
// Десятичное округление вниз
if (!Math.floor10) {
Math.floor10 = function(value, exp) {
return decimalAdjust('floor', value, exp);
};
}
// Десятичное округление вверх
if (!Math.ceil10) {
Math.ceil10 = function(value, exp) {
return decimalAdjust('ceil', value, exp);
};
}
})();
// Округление к ближайшему
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
// Округление вниз
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Округление вверх
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50
Неточные вычисления
Внутри JavaScript число представлено в виде 64-битного формата IEEE-754. Для хранения числа используется 64 бита: 52 из них используется для хранения цифр, 11 из них для хранения положения десятичной точки (если число целое, то хранится 0), и один бит отведён на хранение знака.
Если число слишком большое, оно переполнит 64-битное хранилище, JavaScript вернёт бесконечность:
Наиболее часто встречающаяся ошибка при работе с числами в JavaScript – это потеря точности.
Посмотрите на это (неверное!) сравнение:
Да-да, сумма и не равна .
Странно! Что тогда, если не ?
Но почему это происходит?
Число хранится в памяти в бинарной форме, как последовательность бит – единиц и нулей. Но дроби, такие как , , которые выглядят довольно просто в десятичной системе счисления, на самом деле являются бесконечной дробью в двоичной форме.
Другими словами, что такое ? Это единица делённая на десять — , одна десятая. В десятичной системе счисления такие числа легко представимы, по сравнению с одной третьей: , которая становится бесконечной дробью .
Деление на гарантированно хорошо работает в десятичной системе, но деление на – нет. По той же причине и в двоичной системе счисления, деление на обязательно сработает, а становится бесконечной дробью.
В JavaScript нет возможности для хранения точных значений 0.1 или 0.2, используя двоичную систему, точно также, как нет возможности хранить одну третью в десятичной системе счисления.
Числовой формат IEEE-754 решает эту проблему путём округления до ближайшего возможного числа. Правила округления обычно не позволяют нам увидеть эту «крошечную потерю точности», но она существует.
Пример:
И когда мы суммируем 2 числа, их «неточности» тоже суммируются.
Вот почему – это не совсем .
Не только в JavaScript
Справедливости ради заметим, что ошибка в точности вычислений для чисел с плавающей точкой сохраняется в любом другом языке, где используется формат IEEE 754, включая PHP, Java, C, Perl, Ruby.
Можно ли обойти проблему? Конечно, наиболее надёжный способ — это округлить результат используя метод toFixed(n):
Также можно временно умножить число на 100 (или на большее), чтобы привести его к целому, выполнить математические действия, а после разделить обратно. Суммируя целые числа, мы уменьшаем погрешность, но она все равно появляется при финальном делении:
Таким образом, метод умножения/деления уменьшает погрешность, но полностью её не решает.
Забавный пример
Попробуйте выполнить его:
Причина та же – потеря точности. Из 64 бит, отведённых на число, сами цифры числа занимают до 52 бит, остальные 11 бит хранят позицию десятичной точки и один бит – знак. Так что если 52 бит не хватает на цифры, то при записи пропадут младшие разряды.
Интерпретатор не выдаст ошибку, но в результате получится «не совсем то число», что мы и видим в примере выше. Как говорится: «как смог, так записал».
Два нуля
Другим забавным следствием внутреннего представления чисел является наличие двух нулей: и .
Все потому, что знак представлен отдельным битом, так что, любое число может быть положительным и отрицательным, включая нуль.
В большинстве случаев это поведение незаметно, так как операторы в JavaScript воспринимают их одинаковыми.
拓展 Math 对象
As with most of the built-in objects in JavaScript, the object can be extended with custom properties and methods. To extend the object, you do not use . Instead, you directly extend :
Math.propName = propValue; Math.methodName = methodRef;
For instance, the following example adds a method to the object for calculating the greatest common divisor of a list of arguments.
/* Variadic function -- Returns the greatest common divisor of a list of arguments */
Math.gcd = function() {
if (arguments.length == 2) {
if (arguments == 0)
return arguments;
else
return Math.gcd(arguments, arguments % arguments);
} else if (arguments.length > 2) {
var result = Math.gcd(arguments, arguments);
for (var i = 2; i < arguments.length; i++)
result = Math.gcd(result, arguments);
return result;
}
};
试试运行下面的代码: