...

Метод mathRound

Тема в разделе "Примеры сценариев", создана пользователем kirillovykh, 27 май 2024.

  1. kirillovykh

    kirillovykh Участник

    Проблема неточных вычислений описана в статье справки https://elma365.com/ru/help/platform/js-imprecise-calculations.html
    Также имеется разбор вопросов по округлению https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary

    В связи с этим, при округлении «стандартными» способами могут возникать погрешности.
    Например:
    • для parseFloat("1.555").toFixed(2) результат будет 1.55, а не 1.56
    • для Math.round(1.005 * 100) / 100 результат будет 1, а не 1.01

    Минимизировать ошибку округления возможно при помощи использования константы Number.EPSILON.
    Для удобства переиспользования округление вынесено в метод. На вход число для округления и количество знаков после запятой.
    Код:
    
    function mathRound(valuenumberdigitsnumber) {
        if (!
    Number.isInteger(digits)) {
            return 
    NaN;
        }
        const 
    round 10 ** digits;
        return 
    Math.round((value Number.EPSILON) * round) / round;
    }

    Использование Number.EPSILON также не даёт точного округления в некоторых случаях. Например, для 1.3549999999999998, результат будет 1.35, а не 1.36.

    Более полным решением проблемы будет реализация алгоритма округления https://en.wikipedia.org/wiki/Rounding.
    Либо использование соответствующей библиотеки.

    Также один из вариантов решения рассматривается на китайской версии MDN.