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; } };
试试运行下面的代码: