Округление на Javascript

Javascript

Часто в JavaScript, делая вычисления, можно получить число не в том диапазоне или числа, которые нужно «почистить» перед последующим использованием. Эти числа округляются в меньшую или большую степень, «обрезаются» до нужно количества с помощью знака после запятой или задаются в определенном диапазоне – все зависит от вашей задачи.

Зачем нужно округлять числа?

Наверняка вы знаете, что JavaScript состоит в том, что этот язык не хранит целые числа: они представлены в двоичном виде с плавающей запятой. Этот факт, в сочетании с тем, что не все дроби представляются в виде десятичного числа с конечным количеством цифр после запятой, означает, что в JavaScript можно получить такой результат:

0.1 * 0.2;
> 0.020000000000000004

С практической точки зрения в большинстве случаев данная погрешность не будет иметь значения (одна ошибка на 2 квинтиллиона), однако все же это несколько разочаровывает. Также немного странный результат можно получить, работая с валютами, единицами измерения размера файла или процентными значениями. Чтобы исключить такую неточность, нужно округлить число или ввести после запятой определенное количество знаков.

Округление имеет множество примеров практического применения: например, если пользователь передвигает ползунок элемента range, чтобы не работать с десятичными числами, удобнее было бы округлять полученное значение до ближайшего целого.

Округление десятичных чисел

Чтобы округлить десятичные числа в JavaScript воспользуйтесь методами toPrecision и toFixed(). Оба метода принимают только один аргумент, который задает кол-во знаков после запятой или кол-во «значащих цифр» (то есть общее количество цифр в числе).

Если аргумент не будет задан в 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»

Важно! Оба метода toPrecision() и toFixed() возвращают не число, а округленное представление строки результата. То есть при «сложении» переменных randNum и rounded будет произведено не сложение, а конкатенация:

console.log(randNum + rounded);
> «6.256»

Если необходимо привести результат к числу, воспользуйтесь parseFloat:

var randNum = 6.25;
var rounded = parseFloat(randNum.toFixed(1));
console.log(rounded);
> 6.3

Важно! Чтобы число 5 округлилось в большую сторону, за исключением редких случаев; более детально чуть ниже.)

Также методы toPrecision() и toFixed() бывают полезны, когда целому числу нужно прописать десятичную часть. Это удобно при работе с валютами:

var wholeNum = 1
var dollarsCents = wholeNum.toFixed(2);
console.log(dollarsCents);
> «1.00»

Внимание! Если в числе будет больше цифр, чем в toPrecision, то оно будет записано с мантиссой и порядком (в научном виде):

var num = 123.435
num.toPrecision(2);
> «1.2e+2»

Как исключить ошибки при округлении десятичных чисел

В некоторых случаях toPrecisionи toFixed округляют 5 не вверх, а вниз:

var numTest = 1.005;
numTest.toFixed(2);
> 1;

Результат, приведенный выше, должен быть 1.01, а не 1. Если для вас важна точность, то подошло бы решение от Jack L Moore, который в вычислениях применяет экспоненциальные числа:

function round(value, decimals) {
return Number(Math.round(value+’e’+decimals)+’e-‘+decimals);
}

И результат:

round(1.005,2);
> 1.01

На MDN существует еще более надежное решение.

Усечение десятичных чисел

Все приведенные выше методы округляют десятичные числа. Чтобы усечь положительное число до 2-х знаков после запятой, нужно умножить его на 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

Округление в сторону ближайшего числа

Чтобы округлить десятичное число вниз или вверх до ближайшего целого потребуется метод 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,5) метод Math.floor доставит вам на -3 этаж:

Math.floor(-2.5);
> -3

Чтобы отрицательные числа не округлялись в меньшую сторону, придется воспользоваться 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

Округление вверх и вниз до ближайшего кратного числа

Если нужно округлить число до ближайшего кратного пяти, то проще всего создать функцию, которая бы разделила число на пять, округлила его и умножила обработано:

function roundTo5(num) {
return Math.round(num/5)*5;
}

Результат:

roundTo5(11);
> 10

Если нужно округлять числа под различные кратные, есть смысл изменить функцию и передавать в нее оба значения как аргументы (число и кратность):

function roundToMultiple(num, multiple) {
return Math.round(num/multiple)*multiple;
}

Чтобы вызвать функцию, нужно указать 2 параметра, число и кратность:

var initialNumber = 11;
var multiple = 10;
roundToMultiple(initialNumber, multiple);
> 10;

Чтобы округлить вверх или вниз ставьте в функции floor или ceil.

Установка диапазона для числа

Часто случается, когда мы получаем какое-то число, и нам нужно загнать его в определенный диапазон. Например, нам нужно число от 1 до 100, а получили мы 123. Здесь на помощь придут методы max (самое большое число из набора) и min (возвращает наименьшее из чисел набора). Приведем пример с диапазоном от 1 до 100:

var lowBound = 1;
var highBound = 100;
var numInput = 123;
var clamped = Math.max(lowBound, Math.min(numInput, highBound));
console.log(clamped);
> 100;

Это можно превратить в функцию или расширение Number, вариант с расширением первым предложил Daniel X. Moore:

Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};

Результат:

(numInput).clamp(lowBound, highBound);

Округление по Гауссу

Округление по Гауссу (округление для «банкиров», конвергентное округление, голландское округление и нечетно-четное округление),данный метод округления без статистического смещения; в простом округлении числа автоматически завышаются. В округлении по Гауссу число приводится к ближайшему четному. Лучшее известное решение у Tim Down:

function gaussRound(num, decimalPlaces) {
var 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

Десятичные числа в CSS

Часто JavaScript используют для вычисления значения или позиций трансформации HTML элементов. Вот что будет, если задать элементу десятичное значение:

#box { width: 63.667731993px; }

Преимущество в том, что современные веб-браузеры понимают десятичные значения, которые присвоены к блоковым элементам, включая пиксели и проценты.

Оцените статью
Образовательный портал WELCOME4U.RU
Добавить комментарий

Adblock
detector