Округлить результат javascript в большую сторону. Объект Math в javascript - Методы round, ceil и floor - Округление дробных чисел
Часто вычисления дают результаты, которые не соответствуют пределам нужных диапазонов. В результате нужно осуществлять JavaScript округление до определенного значения.
Для чего округлять числа?JavaScript не хранит целые числа, поскольку их значения представлены в виде цифр с плавающей точкой. Многие дроби не могут быть представлены числом с определенным конечным количеством знаков после запятой, поэтому JavaScript может генерировать результаты, наподобие приведенного ниже:
0.1 * 0.2; > 0.020000000000000004
На практике это не будет иметь никакого значения, поскольку речь идет о погрешности в 2 квинтилионные. Но это может отразиться на результате при работе с числами, которые представляют значения валют, процентов или размер файла. Поэтому нужно сделать или до определенного знака после запятой.
Округление десятичных чиселЧтобы «обрезать » десятичное число, используются методы toFixed() или toPrecision() . Они оба принимают один аргумент, который определяет количество значимых и знаков после запятой, которые должны быть включены в результат:
- если для toFixed() аргумент не определен, значение по умолчанию равно 0 , то есть без знаков после запятой; максимальное значение аргумента равно 20 ;
- если для toPrecision() аргумент не задан, число не изменяется.
var randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" var randNum = 87.335; randNum.toFixed(2); > "87.33" var randNum = 87.337; randNum.toPrecision(3); > "87.3"
Примечание
И toFixed() , и toPrecision возвращают округленное строчное представление результата, а не число. Это означает, что прибавление rounded к randNum в результате даст конкатенацию строк, а не одно число:
console.log(randNum + rounded); > "6.256"
Если нужно получить в результате JavaScript округления до сотых число, используйте parseFloat() :
var randNum = 6.25; var rounded = parseFloat(randNum.toFixed(1)); console.log(rounded); > 6.3
toFixed() и toPrecision() также являются полезными методами для усечения большого количества знаков после запятой. Это удобно при работе с числами, представляющими денежные единицы:
var wholeNum = 1 var dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"
Обратите внимание, что если в числе больше знаков, чем задано параметром точности, toPrecision будет выдавать результат в научном формате:
var num = 123.435 num.toPrecision(2); > "1.2e+2"
Как избежать ошибок при округлении десятичных дробейВ некоторых случаях toFixed и toPrecision осуществляют JavaScript округление 5 в меньшую сторону , а не до большего:
var numTest = 1.005; numTest.toFixed(2); > 1;
Результатом приведенного выше примера должно быть 1.01, а не 1. Если нужно избежать этой ошибки, я рекомендую использовать экспоненциальные числа:
function round(value, decimals) { return Number(Math.round(value+"e"+decimals)+"e-"+decimals); }
Применение:
round(1.005,2); > 1.01
Если нужно еще более надежное решение, чем округление, оно доступно на MDN .
Округление с помощью эпсилонаАльтернативный метод JavaScript округления до десятых был введен в ES6 (также известном, как JavaScript 2015 ). «Машинный эпсилон » обеспечивает разумный предел погрешности при сравнении двух чисел с плавающей запятой. Без округления, сравнения могут дать результаты, подобные следующим:
0.1 + 0.2 === 0.3 > false
Math.EPSILON может быть использован в функции для получения корректного сравнения:
function epsEqu(x, y) { return Math.abs(x - y) < Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
Функция принимает два аргумента : один содержит вычисления, второй ожидаемый (округленный ) результат. Она возвращает сравнение этих двух параметров:
epsEqu(0.1 + 0.2, 0.3) > true
Все современные браузеры поддерживают математические функции ES6 . Но если необходимо обеспечить поддержку в старых браузерах, то нужно использовать полифиллы .
Усечение десятичных чиселВсе методы, представленные ранее, выполняют JavaScript округление до десятых . Чтобы усечь положительное число до двух знаков после запятой, умножить его на 100 , усечь снова, а затем полученный результат разделить на 100 , нужно:
function truncated(num) { return Math.trunc(num * 100) / 100; } truncated(3.1416) > 3.14
Если требуется что-то более гибкое, можно воспользоваться побитовым оператором:
function truncated(num, decimalPlaces) { var numPowerConverter = Math.pow(10, decimalPlaces); return ~~(num * numPowerConverter)/numPowerConverter; }
Использование:
var randInt = 35.874993; truncated(randInt,3); > 35.874
Округление до ближайшего числаЧтобы осуществить JavaScript округление до целого , используется Math.round() :
Math.round(4.3) > 4 Math.round(4.5) > 5
Обратите внимание, что «половинные значения «, такие как .5 , округляются вверх.
Округление вниз до ближайшего целого числаЕсли вы хотите округлять в меньшую сторону, используйте метод Math.floor() :
Math.floor(42.23); > 42 Math.floor(36.93); > 36
Округление «вниз » имеет одно направление для всех чисел, в том числе и для отрицательных. Это можно представить, как небоскреб с бесконечным количеством этажей, в том числе и ниже уровня фундамента (представляющих отрицательные числа ). Если вы находитесь в лифте между подвальными этажами 2 и 3 (что соответствует значению -2.5 ), Math.floor доставит вас на этаж -3 :
Math.floor(-2.5); > -3
Если нужно избежать этого, используйте JavaScript Math округление с помощью Math.trunc() , поддерживаемый во всех современных браузерах (кроме IE / Edge ):
Math.trunc(-41.43); > -41
MDN также предоставляет полифилл из трех строк для обеспечения поддержки Math.trunc в старых браузерах и IE / Edge .
Округление вверх до ближайшего целого числаЕсли вы хотите округлить десятичные числа вверх, используйте Math.ceil . Действие этого метода также можно представить, как бесконечный лифт: Math.ceil всегда везет вас «вверх «, независимо от того, является ли число отрицательным или положительным:
Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); -36
Округление до ближайшего кратного числаЕсли нужно округлить значение до ближайшего числа, кратного 5 , создайте функцию, которая делит число на 5 , округляет его, а затем умножает результат на то же значение:
function roundTo5(num) { return Math.round(num/5)*5; }
Использование:
roundTo5(11); > 10
Если нужно выполнить JavaScript округление до двух знаков, можно передавать функции, как начальное число, так и кратность:
function roundToMultiple(num, multiple) { return Math.round(num/multiple)*multiple; }
Чтобы использовать функцию, включите в ее вызов округляемое число и кратность:
var initialNumber = 11; var multiple = 10; roundToMultiple(initialNumber, multiple); > 10;
Чтобы округлять значения только в большую или меньшую сторону замените в функции round на ceil или floor .
Привязка к диапазонуИногда нужно получить значение х , которое должно находиться в пределах определенного диапазона. Например, нужно значение от 1 до 100 , но мы получаем значение 123 . Чтобы исправить это, можно использовать min() (возвращает наименьшее из чисел ) и max (возвращает максимально допустимое число ).
Использование:
var lowBound = 1; var highBound = 100; var numInput = 123; var clamped = Math.max(lowBound, Math.min(numInput, highBound)); console.log(clamped); > 100;
Можно создать функцию или расширение класса Number .
Часто результатом расчётов бывает число с большим количеством знаков после запятой. Если это число будет использовано для дальнейших расчётов, то его можно оставить в таком виде. Но иногда требуется округление числа, например для вывода на страницу. В JavaScript округление чисел осуществляется несколькими методами.
Метод Math.round() округляет значение до целого числа.
Math.round (число)
Округление числа производится по математическим правилам. То есть, если после запятой идёт цифра от 0 до 4, то дробная часть просто отбрасывается. А если после запятой идёт цифра от 5 до 9, то дробрая часть отбрасывается, а к целой части прибавляется единица. пример:
JavaScript:
Есть ещё два метода, которые округляют число до целого значения. Метод Math.floor() округляет в меньшую сторону. Он отбрасывает дробную часть числа. А метод Math.ceil() округляет в большую сторону. Он отбрасывает дробную часть, а к целой части прибавляет единицу. Пример:
Конечно, 5 - (-2) это 5+2. Не завбывайте, что число 5 Вы в этой формуле не получите. Максимальное будет 4.999999999. Полученные значения можно округлить до нужной точности.
Если нужны только целые числа, то полученные значения можно округлять до целого в меньшую сторону. К максимуму нужно прибавить единицу, чтобы этот максимум тоже был возможен. Формула получается такая:
целое число = Math.floor (минимум + Math.random() * (максимум + 1 - минимум)
Выведем числа от 10 до 15:
20 |
for (i=1; i 0.020000000000000004
0.3 - 0.1
> 0.19999999999999998
Для практических целей эта неточность не имеет никакого значения, в нашем случае мы говорим об ошибке в квинтиллионных долях, однако, кого-то это может разочаровать. Мы можем получить несколько странный результат и при работе с числами, которые представляют собой значения валют, процентов или размеров файла. Для того, чтобы исправить эти неточности, нам как раз и необходимо уметь округлять результаты, при этом достаточно установить десятичную точность. Округление чисел имеет практическое применение, мы можем манипулировать числом в некотором диапазоне, например, хотим округлить значение до ближайшего целого числа, а не работать только с десятичной частью. Округление десятичных чисел Для того, чтобы отсечь десятичное число, используйте toFixed или метод toPrecision . Оба они принимают единственный аргумент, который определяет, соответственно, сколько значащих цифр (т.е. общее количество цифр, используемых в числе) или знаков после запятой (количество после десятичной точки) должен включать в себя результат:Оба метода toFixed() и toPrecision() возвращают строковое представление результата, а не число. Это означает, что при суммировании округленного значения с randNum будет произведена конкатенация строк, а не сумма чисел: Let randNum = 6.25;
let rounded = randNum.toFixed(); // "6"
console.log(randNum + rounded);
> "6.256"
Let randNum = 6.25;
let rounded = parseFloat(randNum.toFixed(1));
console.log(rounded);
> 6.3
Методы toFixed() и toPrecision() являются полезными, ибо они могут не только отсекать дробную часть, но и дополнять знаки после запятой, что удобно при работе с валютой: Let wholeNum = 1
let dollarsCents = wholeNum.toFixed(2);
console.log(dollarsCents);
> "1.00"
Let num = 123.435 num.toPrecision(2); > "1.2e+2" Как избежать ошибок округления с десятичными числами В некоторых случаях, toFixed и toPrecision округляет значение 5 в меньшую сторону, а в большую:Let numTest = 1.005;
numTest.toFixed(2);
> "1.00"
Function round(value, decimals) {
return Number(Math.round(value+"e"+decimals)+"e-"+decimals);
}
Round(1.005,2);
> 1.01
0.1 + 0.2 === 0.3
> false
Function epsEqu(x, y) {
return Math.abs(x - y) < Number.EPSILON * Math.max(Math.abs(x), Math.abs(y));
}
EpsEqu(0.1 + 0.2, 0.3)
> true
Function truncated(num) {
return Math.trunc(num * 100) / 100;
}
truncated(3.1416)
> 3.14
Function truncated(num, decimalPlaces) {
let numPowerConverter = Math.pow(10, decimalPlaces);
return ~~(num * numPowerConverter)/numPowerConverter;
}
Let randInt = 35.874993; truncated(randInt,3); > 35.874 Округление до ближайшего числа Для того, чтобы округлить десятичное число до ближайшего числа в большую или в меньшую сторону, в зависимости от того, к чему мы ближе всего, используйте Math.round():Math.round(4.3)
> 4
Math.round(4.5)
> 5
Math.floor(42.23);
> 42
Math.floor(36.93);
> 36
Math.floor(-2.5);
> -3
Math.trunc(-41.43);
> -41
Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); > -36 Округление до большего/меньшего необходимого числа Если мы хотим, чтобы округлить до ближайшего числа, кратного 5, самый простой способ создать функцию, которая делит число на 5, округляет его, а затем умножает его на ту же сумму:Function roundTo5(num) {
return Math.round(num/5)*5;
}
RoundTo5(11);
> 10
Function roundToMultiple(num, multiple) {
return Math.round(num/multiple)*multiple;
}
Let initialNumber = 11; let multiple = 10; roundToMultiple(initialNumber, multiple); > 10; Фиксирование числа в диапазоне Есть много случаев, когда мы хотим получить значение х, лежащее в пределах диапазона. Например, нам может понадобиться значение от 1 до 100, но при этом мы получили значение 123. Для того, чтобы исправить это, мы можем использовать минимальное (возвращает наименьшее из набора чисел) и максимальное (возвращает наибольшее из любого множества чисел). В нашем примере, диапазон от 1 до 100:Let lowBound = 1;
let highBound = 100;
let numInput = 123;
let clamped = Math.max(lowBound, Math.min(numInput, highBound));
console.log(clamped);
> 100;
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};
NumInput.clamp(lowBound, highBound); > 100; Гауссово округление Гауссово округление, также известное как банковское округлением, заключается в том, что округление для этого случая происходит к ближайшему чётному. Этот метод округления работает без статистической погрешности. Лучшее решение было предложено Tim Down :Function gaussRound(num, decimalPlaces) {
let d = decimalPlaces || 0,
m = Math.pow(10, d),
n = +(d ? num * m: num).toFixed(8),
i = Math.floor(n), f = n - i,
e = 1e-8,
r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 == 0) ? i: i + 1) : Math.round(n);
return d ? r / m: r;
}
GaussRound(2.5)
> 2
gaussRound(3.5)
> 4
gaussRound(2.57,1)
> 2.6
Так как JavaScript часто используется для создания позиционного преобразования HTML-элементов, вы можете задаться вопросом, что произойдет, если мы cгенерируем десятичные значения для наших элементов: #box { width: 63.667731993px; }
Let fruit = ["butternut squash", "apricot", "cantaloupe"];
fruit.sort();
> "apricot", "butternut squash", "cantaloupe"]
Let fruit = ["butternut squash", "apricot", "Cantalope"];
fruit.sort();
> "Cantaloupe", "apricot", "butternut squash"]
Чтобы отсортировать массив, который может содержать смешанные регистры первых букв, нам необходимо либо преобразовать все элементы временно в нижний регистру, или определить свой порядок сортировки при помощи метода localeCompare() c некоторыми аргументами. Как правило, для такого случая, лучше сразу создать функцию для многократного использования: Function alphaSort(arr) {
arr.sort(function (a, b) {
return a.localeCompare(b, "en", {"sensitivity": "base"});
});
}
let fruit = ["butternut squash", "apricot", "Cantaloupe"];
alphaSort(fruit)
> Function alphaSort(arr) {
arr.sort(function (a, b) {
return b.localeCompare(a, "en", {"sensitivity": "base"});
});
}
let fruit = ["butternut squash", "apricot", "Cantaloupe"];
alphaSort(fruit)
> ["Cantaloupe", "butternut squash", "apricot"]
Function caseSort(arr) { arr.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); } let fruit = ["butternut squash", "apricot", "Cantaloupe"]; caseSort(fruit) > ["apricot", "butternut squash", "Cantaloupe"] Числовая сортировка Все это не относится к тому примеру, о котором мы говорили выше про массив игровых рекордов. С некоторыми числовыми массивами сортировка работает просто идеально, но в какой-то момент результат может быть непредсказуемым:Let highScores = ;
highScores.sort();
>
Let highScores = ;
highScores.sort(function(a,b) { return a - b; });
>
Let scores = [
{
"name": "Daniel",
"score": 21768
},
{
"name": "Michael",
"score": 33579
},
{
"name": "Alison",
"score": 38395
}
];
Scores.sort((a, b) => b.score - a.score));
Scores.sort(function(a, b) { return a.score - b.score });
В JavaScript степенная функция представлена как Math.pow(), в новом стандарте ES7 был представлен новый оператор возведения в степень - " * * ". Возведение в степень Для того, чтобы возвести число в n-ую степень, используйте функцию Math.pow(), где первый аргумент это число, которое будет возведено в степень, второй аргумент это показатель степени:Math.pow(3,2)
> 9
Math.pow(5,3);
> 125
ECMAScript 7 - это следующая версия JavaScript, в принципе, мы можем использовать новый предложенный оператор возведения в степень - * *, такая форма записи может быть более наглядной: 3 ** 2
> 9
Степенная функция может пригодиться в самых разных ситуациях. Простой пример, вычисление количества секунд в часе: Math.pow (60,2). Квадратный и кубический корень Math.sqrt() и Math.cbrt() противоположны функции Math.pow(). Как мы помним, квадратный корень из числа a - число, дающее a при возведении в квадрат.Math.sqrt(9)
> 3
Math.cbrt(125)
> 5
Math.pow(1.25, 2);
> 1.5625
Math.cbrt(56.57)
> 3.8387991760286138
Math.pow(-5,2)
> 25
Math.pow(10,-2)
> 0.01
Math.sqrt(-9)
> NaN
Вы можете использовать дробные значения в Math.pow(), чтобы найти квадратные и кубические корни чисел. Квадратный корень использует показатель 0.5: Math.pow(5, 0.5); // = Math.sqrt(5) = 5 ** (1/2)
> 2.23606797749979
Math.pow(2.23606797749979,2)
> 5.000000000000001
Некоторые, по непонятным причинам в JavaScript путают функцию Math.pow() с Math.exp() , которая является экспоненциальной функцией для чисел, в целом. Примечание: в английском языке «показатель степени» переводится как «exponent», поэтому это скорее относится к англоговорящим, хотя существуют и альтернативные названия показателя степени , такие как index, power. Математические константы Работа с математикой в JavaScript облегчается за счет ряда встроенных констант. Эти константы являются свойствами объекта Math. Стоит обратить внимание, что константы пишутся в верхнем регистре, а не CamelCase нотации. Math.abs, parseInt, parseFloat Работа с числами в JavaScript может быть куда более сложной, чем кажется. Полученные значения не всегда попадают внутрь ожидаемых диапазонов, иногда результат может оказаться вовсе не тем, что мы ожидали. Math.abs() Метод Math.abs() возвращает абсолютное значение числа, что напоминает нам аналогичную математическую функцию модуля числа a .Let newVal = -57.64;
Math.abs(newVal);
> 57.64
Math.abs(0); > -0 parseInt() Мы знаем, что JavaScript понимает, что «15» это строка, а не число и, например, при разборе CSS-свойств средствами JavaScript, или получив какое-либо значение из неподготовленного массива, наши результаты могут получиться непредсказуемыми. Мы могли получить на вход строку представленную как «17px», и для нас это не является редкостью. Вопрос заключается в том, как преобразовать эту строку в фактическое значение и использовать его в дальнейших расчетах.Синтаксис: parseInt(string, radix); Функция parseInt преобразует первый переданный ей аргумент в строковый тип, интерпретирует его и возвращает целое число или значение NaN. Результат (если не NaN) является целым числом и представляет собой первый аргумент (string), рассматривающийся как число в указанной системе счисления (radix). Например, основание 10 указывает на преобразование из десятичного числа, 8 - восьмеричного, 16 - шестнадцатеричного и так далее. Если основание больше 10, то для обозначения цифр больше 9 используются буквы. Например, для шестнадцатеричных чисел (основание 16) используются буквы от A до F. Рассмотрим пример работы с CSS-свойствами, где, условно говоря, мы можем получить такое значение: Let elem = document.body;
let centerPoint = window.getComputedStyle(elem).transformOrigin;
> "454px 2087.19px"
Let centers = centerPoint.split(" ");
> ["454px", "2087.19px"]
Let centerX = parseInt(centers, 10);
> 454
let centerY = parseInt(centers, 10);
> 2087
Синтаксис: parseFloat(string) Let FP = "33.33333%";
console.log(parseFloat(FP));
> 33.33333
Мы понимаем, что parseInt() и parseFloat() являются чрезвычайно полезными функциями, важно учитывать, что и тут не обойтись без ошибок, поэтому необходимо проверять диапазон ожидаемых значений и в конечном счете анализировать результат, чтобы гарантировать, что полученные значения верны. Теперь рассмотрим метод floor (в переводе - пол) , который работает противоположно методу ceil , т.е. он округляет дробное число в МЕНЬШУЮ сторону .
var age = 35.97 ; age = Math .floor (age) ; /* Округляем значение переменной age в меньшую сторону */ document.write (age );
Как видите, метод floor округлил число 35.97 до 35 , то есть в меньшую сторону. Несмотря на то, что 0.97 больше 0.5 (см. ) . В этом уроке были рассмотрены методы объекта Math , позволяющими округлять дробные десятичные числа . Теперь нужно выполнить домашнее задание. Ваша задача написать функцию, которая принимает два параметра. На выходе функция должна выводить этот же массив, но при этом все элементы массива, должны быть округлены с помощью указанного во втором параметре метода объекта Math . Исходный массив: var numberArray = ; Сначала решение этого задания может казаться практически идентичным с решениями домашних задач из первых трёх уроков этой темы . Но не все так просто... Решение №1 - Внимание По условию задачи функция должна принимать два параметра - исходный массив и один из методов: "round" , "ceil" или "floor" . Исходя из этого, я пробовал сделать так ...
function
decimal
(anyArray
,method
) /* Создаем функцию с двумя параметрами */
for (i = 0 ; i < anyArray .length ; i ++ ) { anyArray = Math .method (anyArray ); /* При помощи одного из методов объекта Math округляем текущий элемент массива */ document.write (anyArray + " "
) decimal (numberArray, round ) /* Вызываем функцию и указываем для нее два параметра. Но НЕЛЬЗЯ указывать ИМЯ метода в качестве параметра функции */
В этом решении создаем функцию с двумя параметрами, а когда ее вызываем, то в качестве параметров
функции пробуем указать исходный массив и ИМЯ одного методов: Но результата мы не получим, так как НЕЛЬЗЯ указывать ИМЯ метода в качестве параметра функции . Обратите внимание: ведь не случайно в условии задачи имена методов "round" , "ceil" и "floor" заключены в кавычки . decimal (numberArray, "round" ) - но такая запись тоже не будет верной!!! Решение №2 - Корректируем предыдущее решение Можно решить задачу, указав для функции один параметр.
var numberArray = ; function
decimal
(anyArray
) /* Создаем функцию с одним параметром */
for (i = 0 ; i < anyArray .length ; i ++ ) /* Перебираем элементы массива */ { /* При помощи метода round объекта Math округляем текущий элемент массива */ document.write (anyArray + " - Округленный элемент "
) /* Выводим ОКРУГЛЕННЫЙ элемент массива */
decimal (numberArray ) /* Вызываем функцию и указываем один параметр - исходный массив */
Здесь удалось достичь нужного результата: метод round округлил все числа по . Но не выполнено условие , так как функция принимает лишь один параметр. Решение №3 - Функция с двумя параметрами Здесь задача решена правильно. Для этого нужно было вспомнить тему условий в javascript и применить несколько условий одновременно.
var numberArray = ; function
decimal
(anyArray
,method
) if (method
"
) Else if(method
"
) else if(method
"
) }
34.82 - исходный элемент массива 12.9 - исходный элемент массива 17.01 - исходный элемент массива 78.51 - исходный элемент массива Это правильное решение Домашнего задания. Здесь для функции указаны два параметра согласно условию. Попробуйте в последней строке этого решения:
Решение №4 - Функция с двумя параметрами + метод prompt Я решил немного оптимизировать предыдущее решение и добавил метод prompt , который вызывает модальное окно, содержащее поле для ввода информации. Теперь благодаря этому можно будет ввести название одного из методов round , floor или ceil в поле для ввода и получить соответствующий результат.
var numberArray = ; function
decimal
(anyArray
,method
) if (method
== "round"
) /* 1-е условие */
"
) Else if(method
== "ceil"
) /* 2-е условие */
"
) else if(method
== "floor"
) /* 3-е условие */
"
) /* Добавляем метод prompt */
var method = prompt ("Введите один из методов: round, ceil или floor" ); if (method
== "floor"
) /* 1-е условие */
"
) else if (method
== "round"
) /* 2-е условие */
"
) else if (method
== "ceil"
) /* 3-е условие */
"
) else /* Иначе... */
"
) decimal (numberArray, method ) /* Вызываем функцию */
Вот так работают методы round , floor или ceil объекта Math , которые округляют дробные числа. Популярное
|