Zaokrąglić do maksymalnie 2 miejsc po przecinku (tylko w razie potrzeby)

Chciałbym zaokrąglić maksymalnie 2 miejsca po przecinku, ale Tylko jeśli to konieczne .

Wejście:

10
1.7777777
9.1

Wyjście:

10
1.78
9.1

Jak mogę to zrobić w JavaScript?

Author: VicJordan, 2012-08-06

30 answers

Użyj Math.round(num * 100) / 100

 2405
Author: Brian Ustas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-14 20:13:38

Jeśli wartość jest typem tekstowym:

parseFloat("123.456").toFixed(2);

Jeśli wartość jest liczbą:

var numb = 123.23454;
numb = numb.toFixed(2);

Jest minusem, że wartości takie jak 1.5 dadzą "1.50" jako wynik. Poprawka sugerowana przez @ minitech:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

Wydaje się, że Math.round jest lepszym rozwiązaniem. Ale tak nie jest! w niektórych przypadkach będzie Nie zaokrąglać poprawnie:

Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!

Tofixed () również Nie zaokrąglają się poprawnie w niektórych przypadkach (testowane w Chrome v. 55. 0. 2883. 87)!

Przykłady:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

Myślę, że to dlatego, że 1.555 jest w rzeczywistości czymś w rodzaju float 1.55499994 za kulisami.

Rozwiązanie 1 polega na użyciu skryptu z wymaganym algorytmem zaokrąglania, na przykład:

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

Https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

Rozwiązanie 2 ma na celu uniknięcie obliczeń z przodu i pobranie zaokrąglonych wartości z serwera zaplecza.

 2400
Author: A Kunin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 19:39:33

Możesz użyć

function roundToTwo(num) {    
    return +(Math.round(num + "e+2")  + "e-2");
}
Znalazłem to na MDN . Ich sposób pozwala uniknąć problemu z 1.005, który był wspomniany.
roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
 337
Author: MarkG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 16:11:16

Odpowiedź Markga jest prawidłowa. Oto ogólne rozszerzenie dla dowolnej liczby miejsc po przecinku.

Number.prototype.round = function(places) {
  return +(Math.round(this + "e+" + places)  + "e-" + places);
}

Użycie:

var n = 1.7777;    
n.round(2); // 1.78

Test jednostkowy:

it.only('should round floats to 2 places', function() {

  var cases = [
    { n: 10,      e: 10,    p:2 },
    { n: 1.7777,  e: 1.78,  p:2 },
    { n: 1.005,   e: 1.01,  p:2 },
    { n: 1.005,   e: 1,     p:0 },
    { n: 1.77777, e: 1.8,   p:1 }
  ]

  cases.forEach(function(testCase) {
    var r = testCase.n.round(testCase.p);
    assert.equal(r, testCase.e, 'didn\'t get right number');
  });
})
 117
Author: Lavamantis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-01 07:40:59

Można użyć .toFixed(NumberOfDecimalPlaces).

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
 72
Author: Gourav Singla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-18 16:28:29

Żadna z odpowiedzi znalezionych tutaj nie jest poprawna . @stinkycheeseman poprosił o zaokrąglenie , wszyscy zaokrągliliście liczbę.

Aby zaokrąglić, użyj tego:

Math.ceil(num * 100)/100;
 55
Author: machineaddict,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-02 08:18:35

Precyzyjna metoda zaokrąglania. Źródło: Mozilla

(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[type](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[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
        // Shift back
        value = value.toString().split('e');
        return +(value[0] + 'e' + (value[1] ? (+value[1] + 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);
        };
    }
})();

Przykłady:

// 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
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
// 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
 55
Author: user,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 19:46:02

To pytanie jest skomplikowane.

Załóżmy, że mamy funkcję roundTo2DP(num), która przyjmuje float jako argument i zwraca wartość zaokrągloną do 2 miejsc po przecinku. Do czego należy oceniać każde z tych wyrażeń?

  • roundTo2DP(0.014999999999999999)
  • roundTo2DP(0.0150000000000000001)
  • roundTo2DP(0.015)

'oczywistą' odpowiedzią jest to, że pierwszy przykład powinien zaokrąglać się do 0.01 (ponieważ jest bliżej 0.01 niż 0.02) , podczas gdy dwa pozostałe powinny zaokrąglać się do 0.02 (ponieważ 0.0150000000000000001 jest bliżej 0.0150000000000000000001 jest bliżej 0.015000000 0,02 niż 0,01, a ponieważ 0,015 jest dokładnie w połowie drogi między nimi i istnieje matematyczna konwencja, że takie liczby są zaokrąglane w górę).

Haczyk, który można się domyślić, jest taki, że roundTo2DP nie można zaimplementować , aby dać te oczywiste odpowiedzi, ponieważ wszystkie trzy liczby przekazane do niego to ta sama liczba . IEEE 754 binarne liczby zmiennoprzecinkowe (rodzaj używany przez JavaScript) nie może dokładnie reprezentować większości liczb nie-całkowitych, a więc wszystkie trzy liczby literały powyżej są zaokrąglane do pobliskiej poprawnej liczby zmiennoprzecinkowej. Liczba ta, tak się składa, to dokładnie

0.01499999999999999944488848768742172978818416595458984375

Który jest bliższy 0,01 niż 0,02.

Możesz zobaczyć, że wszystkie trzy liczby są takie same w konsoli przeglądarki, powłoce węzła lub innym interpreterze JavaScript. Wystarczy je porównać:

> 0.014999999999999999 === 0.0150000000000000001
true

Więc kiedy piszę m = 0.0150000000000000001, dokładna wartość m że kończę z bliżej 0.01 niż do 0.02. A jednak, jeśli przekonwertuję m na ciąg znaków...

> var m = 0.0150000000000000001;
> console.log(String(m));
0.015
> var m = 0.014999999999999999;
> console.log(String(m));
0.015

... Otrzymuję 0,015, które powinno być zaokrąglone do 0,02, A które jest zauważalnie , a nie 56-dziesiętną liczbą, którą wcześniej powiedziałem, że wszystkie te liczby są dokładnie równe. Co to za czarna magia?

Odpowiedź można znaleźć w specyfikacji ECMAScript, w sekcji 7.1.12.1: ToString zastosowany do typu liczby. Tutaj Zasady konwertowania niektórych Liczby m do Ciągu są określone. Kluczowa część to punkt 5, w którym generowana jest liczba całkowita s, której cyfry zostaną użyte w reprezentacji ciągu znaków m :

Niech n, k i s być liczbami całkowitymi takimi, że k ≥ 1, 10k-1s k, wartość liczby dla s × 10n-k jest m , oraz k jest jak najmniejszy. Należy zauważyć, że k jest liczbą cyfr w reprezentacji dziesiętnej s, że s nie jest podzielna przez 10 i że najmniej znacząca cyfra s niekoniecznie jest jednoznacznie określona przez te kryteria.

Kluczową częścią jest tutaj wymóg, aby " k był jak najmniejszy". Wymaganie to jest wymogiem, że biorąc pod uwagę liczbę m, wartość String(m) musi mieć najmniejszą możliwą liczbę cyfr przy jednoczesnym spełnieniu wymogu, że Number(String(m)) === m. Ponieważ już wiemy, że 0.015 === 0.0150000000000000001, Teraz jest jasne, dlaczego String(0.0150000000000000001) === '0.015' musi być prawdą.

Oczywiście żadna z tej dyskusji nie odpowiedziała wprost na to, co roundTo2DP(m) should return. Jeśli m'S dokładna wartość jest 0.01499999999999999999999444888848768742172978818416595458984375, ale jego reprezentacja ciąg jest '0.015', to jaka jest poprawna odpowiedź - matematycznie, praktycznie, filozoficznie, czy cokolwiek-kiedy zaokrąglamy to do dwóch miejsc po przecinku?

Nie ma jednej poprawnej odpowiedzi na to pytanie. To zależy od Twojego przypadku użycia. Prawdopodobnie chcesz respektować reprezentację ciągu I zaokrąglać w górę, gdy:

  • reprezentowana wartość jest z natury Dyskretna, np. kwota waluty w walucie o 3 miejsca po przecinku, takiej jak Dinary. W tym przypadku, true wartość liczby takiej jak 0.015 wynosi 0.015, a 0.0149999999... reprezentacja, którą otrzymuje w binarnym punkcie zmiennoprzecinkowym, jest błędem zaokrąglania. (Oczywiście, wielu będzie argumentować, rozsądnie, że należy używać biblioteki dziesiętnej do obsługi takich wartości i nigdy nie reprezentować ich jako binarnych liczb zmiennoprzecinkowych w pierwszej kolejności.)
  • wartość została wpisana przez użytkownika. W tym przypadku, ponownie, dokładna liczba dziesiętna wprowadzona jest bardziej "prawdziwa" niż najbliższa binarna reprezentacja zmiennoprzecinkowa.

Z drugiej strony, prawdopodobnie chcesz szanować binarna wartość zmiennoprzecinkowa i zaokrąglana w dół, gdy wartość pochodzi ze skali ciągłej-na przykład, jeśli jest to odczyt z czujnika.

Te dwa podejścia wymagają innego kodu. Aby respektować reprezentację ciągu liczb, możemy (z dość subtelnym kodem) zaimplementować nasze własne zaokrąglanie, które działa bezpośrednio na reprezentację ciągu, cyfra po cyfrze, używając tego samego algorytmu, którego użyłbyś w szkole, gdy uczyłeś się zaokrąglać liczby. Poniżej znajduje się przykład, który respektuje wymóg OP, aby reprezentować liczbę do 2 miejsc po przecinku "tylko wtedy, gdy jest to konieczne", usuwając końcowe zera po przecinku; oczywiście możesz potrzebować dostosować go do swoich dokładnych potrzeb.

/**
 * Converts num to a decimal string (if it isn't one already) and then rounds it
 * to at most dp decimal places.
 *
 * For explanation of why you'd want to perform rounding operations on a String
 * rather than a Number, see http://stackoverflow.com/a/38676273/1709587
 *
 * @param {(number|string)} num
 * @param {number} dp
 * @return {string}
 */
function roundStringNumberWithoutTrailingZeroes (num, dp) {
    if (arguments.length != 2) throw new Error("2 arguments required");

    num = String(num);
    if (num.indexOf('e+') != -1) {
        // Can't round numbers this large because their string representation
        // contains an exponent, like 9.99e+37
        throw new Error("num too large");
    }
    if (num.indexOf('.') == -1) {
        // Nothing to do
        return num;
    }

    var parts = num.split('.'),
        beforePoint = parts[0],
        afterPoint = parts[1],
        shouldRoundUp = afterPoint[dp] >= 5,
        finalNumber;

    afterPoint = afterPoint.slice(0, dp);
    if (!shouldRoundUp) {
        finalNumber = beforePoint + '.' + afterPoint;
    } else if (/^9+$/.test(afterPoint)) {
        // If we need to round up a number like 1.9999, increment the integer
        // before the decimal point and discard the fractional part.
        finalNumber = Number(beforePoint)+1;
    } else {
        // Starting from the last digit, increment digits until we find one
        // that is not 9, then stop
        var i = dp-1;
        while (true) {
            if (afterPoint[i] == '9') {
                afterPoint = afterPoint.substr(0, i) +
                             '0' +
                             afterPoint.substr(i+1);
                i--;
            } else {
                afterPoint = afterPoint.substr(0, i) +
                             (Number(afterPoint[i]) + 1) +
                             afterPoint.substr(i+1);
                break;
            }
        }

        finalNumber = beforePoint + '.' + afterPoint;
    }

    // Remove trailing zeroes from fractional part before returning
    return finalNumber.replace(/0+$/, '')
}

Przykładowe użycie:

> roundStringNumberWithoutTrailingZeroes(1.6, 2)
'1.6'
> roundStringNumberWithoutTrailingZeroes(10000, 2)
'10000'
> roundStringNumberWithoutTrailingZeroes(0.015, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.015000', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(1, 1)
'1'
> roundStringNumberWithoutTrailingZeroes('0.015', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(0.01499999999999999944488848768742172978818416595458984375, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.01499999999999999944488848768742172978818416595458984375', 2)
'0.01'

Powyższa funkcja to prawdopodobnie to, czego chcesz użyć, aby uniknąć nieprawidłowego zaokrąglania przez użytkowników wprowadzonych liczb.

(jako alternatywę można wypróbuj również bibliotekę round10 , która zapewnia podobnie zachowującą się funkcję z szalenie inną implementacją.)

Ale co, jeśli masz drugi rodzaj liczby-wartość wziętą ze skali ciągłej, gdzie nie ma powodu, aby sądzić, że przybliżone reprezentacje dziesiętne z mniejszą liczbą dziesiętną są bardziej dokładne niż te z większą liczbą? W takim przypadku, nie chcemy respektować reprezentację łańcuchową, ponieważ ta reprezentacja (jako nie chcemy popełnić błędu mówiąc " 0.014999999...375 rund do 0,015, co zaokrągla się do 0,02, więc 0,014999999...375 nabojów do 0,02".

Tutaj możemy po prostu użyć wbudowanego toFixed metoda. Zauważ, że wywołując {[23] } na łańcuchu zwracanym przez toFixed, otrzymujemy liczbę, której reprezentacja łańcuchowa nie ma końcowych zer (dzięki sposobowi, w jaki JavaScript oblicza reprezentację łańcuchową liczby, omówionej wcześniej w tej odpowiedzi).

/**
 * Takes a float and rounds it to at most dp decimal places. For example
 *
 *     roundFloatNumberWithoutTrailingZeroes(1.2345, 3)
 *
 * returns 1.234
 *
 * Note that since this treats the value passed to it as a floating point
 * number, it will have counterintuitive results in some cases. For instance,
 * 
 *     roundFloatNumberWithoutTrailingZeroes(0.015, 2)
 *
 * gives 0.01 where 0.02 might be expected. For an explanation of why, see
 * http://stackoverflow.com/a/38676273/1709587. You may want to consider using the
 * roundStringNumberWithoutTrailingZeroes function there instead.
 *
 * @param {number} num
 * @param {number} dp
 * @return {number}
 */
function roundFloatNumberWithoutTrailingZeroes (num, dp) {
    var numToFixedDp = Number(num).toFixed(dp);
    return Number(numToFixedDp);
}
 55
Author: Mark Amery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 20:07:48
 51
Author: AceCorban,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 12:25:59

Oto prosty sposób na to:

Math.round(value * 100) / 100

Możesz zrobić oddzielną funkcję, aby zrobić to za Ciebie:

function roundToTwo(value) {
    return(Math.round(value * 100) / 100);
}

Wtedy po prostu podasz wartość.

Można go zwiększyć, aby zaokrąglać do dowolnej liczby miejsc po przecinku, dodając drugi parametr.

function myRound(value, places) {
    var multiplier = Math.pow(10, places);

    return (Math.round(value * multiplier) / multiplier);
}
 42
Author: JayDM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 12:25:44

Powinieneś użyć:

Math.round( num * 100 + Number.EPSILON ) / 100

Nikt nie zdaje sobie sprawy z Number.EPSILON.

Warto również zauważyć, że nie jest to dziwność JavaScript , jak niektórzy stwierdzili.

Jest to po prostu sposób działania liczb zmiennoprzecinkowych w komputerze. podobnie jak 99% języków programowania, JavaScript nie ma domowych liczb zmiennoprzecinkowych; w tym celu opiera się na CPU/FPU. Komputer używa binarnych, a w binarnych nie ma takich liczb jak 0.1, ale zwykłe przybliżenie binarne. Dlaczego? Z tego samego powodu niż 1/3 nie można zapisać dziesiętnie: jego wartość wynosi 0.33333333... z nieskończonością trójek.

Here come Number.EPSILON. Liczba ta jest różnicą między 1 A następną liczbą istniejącą w liczbach zmiennoprzecinkowych o podwójnej precyzji. to jest to: nie ma liczby pomiędzy 1 A 1 + Number.EPSILON.

EDIT:

Zgodnie z pytaniami w komentarzach, wyjaśnijmy jedną rzecz: dodanie Number.EPSILON ma znaczenie tylko wtedy, gdy wartość round jest wynikiem operacji arytmetycznej, ponieważ może pochłonąć pewien zmiennoprzecinkowy błąd delta.

Nie jest użyteczne, gdy wartość pochodzi z bezpośredniego źródła (np.: literal, wejście użytkownika lub czujnik).

 36
Author: cronvel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-08 12:29:55
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
 35
Author: user3711536,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-25 10:27:07

2017
Wystarczy użyć kodu natywnego .toFixed()

number = 1.2345;
number.toFixed(2) // "1.23"

Jeśli musisz być ścisły i dodawać cyfry tylko w razie potrzeby, możesz użyć replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');
 33
Author: pery mimon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 09:56:22

Spróbuj tego lekkiego rozwiązania:

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222
 30
Author: petermeissner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 10:21:12

Jest na to kilka sposobów. Dla ludzi takich jak ja, wariant Lodash

function round(number, precision) {
    var pair = (number + 'e').split('e')
    var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
    pair = (value + 'e').split('e')
    return +(pair[0] + 'e' + (+pair[1] - precision))
}

Użycie:

round(0.015, 2) // 0.02
round(1.005, 2) // 1.01

Jeśli twój projekt używa jQuery lub lodash, możesz również znaleźć odpowiednią metodę round w bibliotekach.

Update 1

Usunąłem wariant n.toFixed(2), ponieważ nie jest poprawny. Thank you @avalanche1

 24
Author: stanleyxu2005,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-22 13:48:11

Dla mnie Matematyka.round () nie dawało poprawnej odpowiedzi. Znalazłem tofixed(2) działa lepiej. Poniżej znajdują się przykłady obu:

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer
 24
Author: VicJordan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 00:32:34

MarkG i Lavamantis zaproponowali znacznie lepsze rozwiązanie niż to, które zostało przyjęte. Szkoda, że nie dostają więcej upvotes!

Oto funkcja, której używam do rozwiązywania problemów z przecinkami zmiennoprzecinkowymi również opartych na MDN . Jest jeszcze bardziej ogólne (ale mniej zwięzłe) niż rozwiązanie Lavamantis: {]}

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp  = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

Użyj z:

round(10.8034, 2);      // Returns 10.8
round(1.275, 2);        // Returns 1.28
round(1.27499, 2);      // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46
W porównaniu z rozwiązaniem Lavamantis, możemy to zrobić...
round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123
 21
Author: astorije,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 15:44:06
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) tutaj 2 to liczba cyfr do której chcemy zaokrąglić tę liczbę.

 16
Author: Ritesh Dhuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-02 07:15:38

Lodash lodash jest biblioteką, w której można użyć metody lodash, jak poniżej.

_.round(number, precision)

Eg:

_.round(1.7777777, 2) = 1.78
 14
Author: Madura Pradeep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-28 06:59:19

To może Ci pomóc:

var result = (Math.round(input*100)/100);

Aby uzyskać więcej informacji, możesz spojrzeć na ten link

Matematyka.runda (num) vs num.tofixed (0) i niespójności przeglądarki

 13
Author: totten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:00

Najprostszy sposób:

+num.toFixed(2)

Konwertuje go do ciągu znaków, a następnie z powrotem do liczby całkowitej / zmiennoprzecinkowej.

 12
Author: Edmund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-25 20:09:30

Oto metoda prototypowa:

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);
 10
Author: arielf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 19:43:00

To może działać dla ciebie,

Math.round(num * 100)/100;

Aby poznać różnicę między tofixed a round. Możesz rzucić okiem na Matematyka.runda (num) vs num.tofixed (0) i niespójności przeglądarki.

 9
Author: Shreedhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 19:36:50

Ogólnie zaokrąglanie odbywa się przez skalowanie: round(num / p) * p

Używając notacji wykładniczej, poprawnie zaokrąglamy liczby + ve. Jednak ta metoda nie zaokrągla przypadków krawędziowych prawidłowo.

function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

// testing some edge cases
console.log( round(1.005, 2) );  // 1.01 correct
console.log( round(2.175, 2) );  // 2.18 correct
console.log( round(5.015, 2) );  // 5.02 correct

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong

Tutaj jest też jedna funkcja, którą napisałem, aby poprawnie zaokrąglać arytmetyczne. Możesz sam to przetestować.

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct
 9
Author: Amr Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 10:23:22

Użyj czegoś takiego "parseFloat(parsefloat (value).toFixed (2)) "

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1
 9
Author: Arulraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 08:26:56

Jeśli zdarzy ci się, że już używasz biblioteki d3, mają one potężną bibliotekę formatowania liczb: https://github.com/mbostock/d3/wiki/Formatting

Zaokrąglenie jest tutaj: https://github.com/mbostock/d3/wiki/Formatting#d3_round

W Twoim przypadku odpowiedź brzmi:

> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
 8
Author: Scott Stafford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-18 13:35:04

Jednym ze sposobów osiągnięcia takiego zaokrąglenia tylko w razie potrzeby jest użycie liczby .prototyp.toLocaleString():

myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})

Zapewni to dokładnie takie wyjście, jakiego oczekujesz, ale jako ciągi znaków. Nadal możesz przekonwertować je z powrotem na liczby, jeśli nie jest to typ danych, którego oczekujesz.

 8
Author: Javarome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-22 21:32:54

Prostszym sposobem ES6 jest

const round = (x, n) => 
  parseFloat(Math.round(x * Math.pow(10, n)) / Math.pow(10, n)).toFixed(n);

Ten wzór zwraca również żądaną precyzję.

Ex:

round(44.7826456, 4)  // yields 44.7826
round(78.12, 4)       // yields 78.1200
 8
Author: Adam A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-01 15:47:40

Ponieważ ES6 istnieje 'właściwy' sposób (bez nadpisywania statyki i tworzenia obejść), aby to zrobić przez używając toPrecision

var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));
 8
Author: Matas Vaitkevicius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 09:25:20

Aby nie radzić sobie z wieloma zerami, użyj tego wariantu:

Math.round(num * 1e2) / 1e2
 7
Author: Daniel De León,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-11 15:21:39