web-dev-qa-db-fra.com

Maths JavaScript, arrondis à deux décimales

J'ai la syntaxe JavaScript suivante:

var discount = Math.round(100 - (price / listprice) * 100);

Ceci arrondit au nombre entier. Comment puis-je renvoyer le résultat avec deux décimales?

379
Smudger

NOTE - Voir Edit 4 si la précision à 3 chiffres est importante

var discount = (price / listprice).toFixed(2);

toFixed arrondira pour vous en fonction des valeurs supérieures à 2 décimales.

Exemple: http://jsfiddle.net/calder12/tv9HY/

Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Edit - Comme mentionné par d'autres, cela convertit le résultat en chaîne. Pour éviter cela:

var discount = +((price / listprice).toFixed(2));

Edit 2 - Comme indiqué également dans les commentaires, cette fonction échoue avec une certaine précision. Dans le cas de 1.005 par exemple, elle retournera 1.00 au lieu de 1.01. Si la précision à ce degré est importante, j'ai trouvé la réponse suivante: https://stackoverflow.com/a/32605063/1726511 Ce qui semble bien fonctionner avec tous les tests que j'ai essayés.

Cependant, une modification mineure est requise, la fonction dans la réponse liée ci-dessus renvoie des nombres entiers lorsqu'elle arrondit à un. Ainsi, par exemple, 99.004 renverra 99 au lieu de 99.00, ce qui n'est pas idéal pour afficher les prix.

Éditer 3 - On dirait que le toFixed sur le retour réel était ENCORE foiré quelques chiffres, cette édition finale semble fonctionner. Décidément, tellement de retouches!

   var discount = roundTo((price / listprice), 2);

   function roundTo(n, digits) {
     if (digits === undefined) {
       digits = 0;
     }

     var multiplicator = Math.pow(10, digits);
     n = parseFloat((n * multiplicator).toFixed(11));
     var test =(Math.round(n) / multiplicator);
     return +(test.toFixed(digits));
   }

Voir Fiddle exemple ici: https://jsfiddle.net/calder12/3Lbhfy5s/

Edit 4 - Vous me tuez, les gars. Edit 3 échoue sur les nombres négatifs, sans comprendre pourquoi il est tout simplement plus facile de rendre positif un nombre négatif avant d'arrondir, puis de le retourner avant de renvoyer le résultat.

function roundTo(n, digits) {
    var negative = false;
    if (digits === undefined) {
        digits = 0;
    }
        if( n < 0) {
        negative = true;
      n = n * -1;
    }
    var multiplicator = Math.pow(10, digits);
    n = parseFloat((n * multiplicator).toFixed(11));
    n = (Math.round(n) / multiplicator).toFixed(2);
    if( negative ) {    
        n = (n * -1).toFixed(2);
    }
    return n;
}

Violon: https://jsfiddle.net/3Lbhfy5s/79/

718
Rick Calder

Si vous utilisez un unaire plus pour convertir une chaîne en un nombre comme documenté sur MDN .

Par exemple: +discount.toFixed(2)

125
John Gietzen

Les fonctions Math.round () et .toFixed () sont censées être arrondies à l'entier le plus proche. Vous obtiendrez des résultats incorrects lorsque vous utiliserez des nombres décimaux et que vous utiliserez la méthode "multiplier et diviser" pour Math.round () ou le paramètre pour .toFixed (). Par exemple, si vous essayez d'arrondir 1,005 en utilisant Math.round (1,005 * 100)/100, vous obtiendrez le résultat de 1 et 1,00 en utilisant .toFixed (2) au lieu d'obtenir la réponse correcte de 1,01.

Vous pouvez utiliser ce qui suit pour résoudre ce problème:

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2');

Ajoutez .toFixed (2) pour obtenir les deux décimales souhaitées.

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2').toFixed(2);

Vous pouvez créer une fonction qui gérera l’arrondi:

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

Exemple: https://jsfiddle.net/k5tpq3pd/36/

Alternativ

Vous pouvez ajouter une fonction d'arrondi à Nombre à l'aide d'un prototype. Je ne suggérerais pas d'ajouter .toFixed () ici car cela renverrait une chaîne au lieu d'un nombre.

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

et l'utiliser comme ça:

var numberToRound = 100 - (price / listprice) * 100;
numberToRound.round(2);
numberToRound.round(2).toFixed(2); //Converts it to string with two decimals

Exemple https://jsfiddle.net/k5tpq3pd/35/

Source: http://www.jacklmoore.com/notes/rounding-in-javascript/

42
Arne H. Bitubekk

Pour obtenir le résultat avec deux décimales, procédez comme suit:

var discount = Math.round((100 - (price / listprice) * 100) * 100) / 100;

La valeur à arrondir est multipliée par 100 pour conserver les deux premiers chiffres, puis divisée par 100 pour obtenir le résultat réel.

29
Cattode

La solution la meilleure et simple que j'ai trouvée est

function round(value, decimals) {
 return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}   
round(1.005, 2); // 1.01
15
Naga Srinu Kapusetti

essayez d'utiliser discount.toFixed(2);

14
Harish

Je pense que la meilleure façon de le faire est de multiplier par 10 la puissance du nombre de chiffres, puis de faire un calcul mathématique, puis de diviser par 10 par la puissance de chiffres. Voici une fonction simple que j'utilise dans TypeScript:

function roundToXDigits(value: number, digits: number) {
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

Ou simplement en javascript:

function roundToXDigits(value, digits) {
    if(!digits){
        digits = 2;
    }
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}
12
Bryce

Une petite variation sur la réponse acceptée. toFixed(2) renvoie une chaîne et vous obtiendrez toujours deux décimales. Celles-ci pourraient être des zéros. Si vous souhaitez supprimer le zéro final, procédez comme suit:

var discount = + ((price / listprice).toFixed(2));

Édité: Je viens de découvrir ce qui semble être un bogue dans Firefox 35.0.1, ce qui signifie que ce qui précède peut donner à NaN certaines valeurs.
J'ai changé mon code en

var discount = Math.round(price / listprice * 100) / 100;

Cela donne un nombre avec jusqu'à deux décimales. Si vous en vouliez trois, vous multiplieriez et diviseriez par 1000, et ainsi de suite.
Le PO veut toujours deux décimales, mais si toFixed () est cassé dans Firefox, il doit d'abord être corrigé.
Voir https://bugzilla.mozilla.org/show_bug.cgi?id=1134388

7
HalfTitle

moyen le plus rapide - plus rapide que toFixed ():

DEUX DÉCIMAUX

x      = .123456
result = Math.round(x * 100) / 100  // result .12

TROIS DÉCIMAUX

x      = .123456
result = Math.round(x * 1000) / 1000      // result .123
5
Kamy D
    function round(num,dec)
    {
      num = Math.round(num+'e'+dec)
      return Number(num+'e-'+dec)
    }
      //Round to a decimal of your choosing:
    round(1.3453,2)
3
Chris Martin

Pour traiter les arrondis à un nombre quelconque de décimales, une fonction avec 2 lignes de code suffira pour la plupart des besoins. Voici quelques exemples de code avec lesquels jouer.



    var testNum = 134.9567654;
    var decPl = 2;
    var testRes = roundDec(testNum,decPl);  
    alert (testNum + ' rounded to ' + decPl + ' decimal places is ' + testRes);

    function roundDec(nbr,dec_places){
        var mult = Math.pow(10,dec_places);
        return Math.round(nbr * mult) / mult;
    }

0
user3232196
function discoverOriginalPrice(discountedPrice, salePercentage) {
  var originalPrice = discountedPrice / (1 - (salePercentage * .01));
  return +originalPrice.toFixed(2);
}
0
James Kip