web-dev-qa-db-fra.com

Arrondir à au plus 2 décimales (seulement si nécessaire)

J'aimerais arrondir au maximum 2 décimales, mais niquement si nécessaire.

Contribution:

10
1.7777777
9.1

Sortie:

10
1.78
9.1

Comment puis-je faire cela en JavaScript?

2355
stinkycheeseman

Utilisez Math.round(num * 100) / 100

2972
Brian Ustas

Si la valeur est un type de texte:

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

Si la valeur est un nombre:

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

Il y a un inconvénient: des valeurs comme 1.5 donneront "1.50" en sortie. Un correctif suggéré par @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.

Il semble que Math.round soit une meilleure solution. Mais ce n'est pas! Dans certains cas, il PAS correctement:

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

toFixed () va également PAS correctement dans certains cas (testé dans Chrome v.55.0.2883.87)!

Exemples:

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.

Je suppose que c’est parce que 1.555 est en réalité quelque chose comme le flotteur 1.55499994 dans les coulisses.

La solution 1 consiste à utiliser un script avec l'algorithme d'arrondi requis, par exemple:

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

La solution 2 consiste à éviter les calculs frontaux et à extraire les valeurs arrondies du serveur principal.

2760
A Kunin

Vous pouvez utiliser

function roundToTwo(num) {    
    return +(Math.round(num + "e+2")  + "e-2");
}

J'ai trouvé ceci sur MDN . Leur chemin évite le problème avec 1.005 qui était mentionné .

roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
411
MarkG

La réponse de MarkG est la bonne. Voici une extension générique pour n'importe quel nombre de décimales.

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

Usage:

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

Test de l'unité:

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');
  });
})
135
Lavamantis

On peut utiliser .toFixed(NumberOfDecimalPlaces).

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
79
Gourav Singla

Considérons .toFixed() et .toPrecision():

http://www.javascriptkit.com/javatutors/formatnumber.shtml

67
AceCorban

Cette question est compliquée.

Supposons que nous ayons une fonction, roundTo2DP(num), qui prend un float en argument et renvoie une valeur arrondie à 2 décimales. Que doit évaluer chacune de ces expressions?

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

La réponse "évidente" est que le premier exemple devrait arrondir à 0,01 (car il est plus proche de 0,01 que 0,02), tandis que les deux autres devraient arrondir à 0,02 (parce que 0,0150000000000000001 est plus proche de 0,02 que 0,01 et que 0,015 est exactement à mi-chemin entre et il existe une convention mathématique selon laquelle ces nombres sont arrondis).

Le problème, que vous avez peut-être deviné, est que roundTo2DP ne peut probablement pas être mis en œuvre pour donner ces réponses évidentes, car les trois nombres qui lui sont transmis sont le même numéro . Les nombres à virgule flottante binaires IEEE 754 (le type utilisé par JavaScript) ne peuvent pas représenter exactement la plupart des nombres non entiers, et les trois littéraux numériques ci-dessus sont arrondis à un nombre à virgule flottante valide proche. Ce nombre, en l'occurrence, est exactement

0.0149999999999999999944488848768742172978818416595458984375

qui est plus proche de 0,01 que de 0,02.

Vous pouvez constater que les trois numéros sont identiques sur la console de votre navigateur, Node Shell ou un autre interpréteur JavaScript. Il suffit de les comparer:

> 0.014999999999999999 === 0.0150000000000000001
true

Ainsi, lorsque j'écris m = 0.0150000000000000001, le valeur exacte de m avec lequel je me retrouve est plus proche de 0.01 que de 0.02. Et pourtant, si je convertis m en String ...

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

... Je reçois 0,015, ce qui devrait arrondir à 0,02, ce qui est sensiblement not le nombre à 56 décimales que j’avais précédemment indiqué que tous ces nombres étaient exactement égaux à. Alors, quelle magie noire est-ce?

La réponse se trouve dans la spécification ECMAScript, dans la section 7.1.12.1: ToString appliqué au type Number . Ici, les règles pour convertir un nombre m en chaîne sont définies. La partie clé est le point 5, dans lequel est généré un entier s dont les chiffres seront utilisés dans la représentation sous forme de chaîne de m :

soit n , k , et s être des entiers tels que k ≥ 1, 10k-1 ≤ s <10k, la valeur numérique pour s × 10n-k est m , et k = aussi petit que possible. Notez que k est le nombre de chiffres dans la représentation décimale de s , que s n'est pas divisible par 10, et que le le chiffre le moins significatif de s n'est pas nécessairement déterminé uniquement par ces critères.

La partie clé ici est l'exigence que " k soit aussi petit que possible". Cela correspond à une exigence selon laquelle, étant donné le numéro m, la valeur de String(m) doit avoir le plus petit nombre possible de chiffres tout en satisfaisant à l'exigence Number(String(m)) === m. Puisque nous savons déjà que 0.015 === 0.0150000000000000001, nous comprenons maintenant pourquoi String(0.0150000000000000001) === '0.015' doit être vrai.

Bien sûr, aucune partie de cette discussion n'a directement répondu à ce que roundTo2DP(m) devrait ==. Si la valeur exacte de m est 0.014999999999999999444888768742172972817298818416595458984375, mais que sa représentation sous forme de chaîne est '0.015', alors quelle est la correct - mathématiquement, pratiquement, philosophically, ou quoi que nous ayons arrondi décimales?

Il n'y a pas une seule bonne réponse à cela. Cela dépend de votre cas d'utilisation. Vous voudrez probablement respecter la représentation des chaînes et arrondir à la hausse lorsque:

  • La valeur représentée est intrinsèquement discrète, par ex. un montant de devise dans une devise à 3 décimales, comme les dinars. Dans ce cas, la true valeur d'un nombre tel que 0.015 est 0.015 et la représentation 0.0149999999 ... qu'il entre en la virgule flottante binaire est une erreur d'arrondi. (Bien entendu, nombreux sont ceux qui soutiendront raisonnablement qu'il est préférable d'utiliser une bibliothèque décimale pour gérer ces valeurs et de ne jamais les représenter sous la forme de nombres à virgule flottante binaire.)
  • La valeur a été saisie par un utilisateur. Dans ce cas encore, le nombre décimal exact entré est plus vrai que la représentation en virgule flottante binaire la plus proche.

D'autre part, vous voudrez probablement respecter la valeur en virgule flottante binaire et arrondir vers le bas lorsque votre valeur provient d'une échelle intrinsèquement continue - par exemple, s'il s'agit d'une lecture d'un capteur.

Ces deux approches nécessitent un code différent. Pour respecter la représentation du nombre sous forme de chaîne, nous pouvons (avec un code assez subtil) implémenter notre propre arrondi qui agit directement sur la représentation sous forme de chaîne, chiffre par chiffre, en utilisant le même algorithme que celui que vous auriez utilisé à l'école. ont appris à arrondir les nombres. Vous trouverez ci-dessous un exemple qui respecte l'exigence de l'OP consistant à représenter le nombre à 2 décimales "uniquement lorsque cela est nécessaire" en supprimant les zéros à la fin du point décimal; vous pouvez, bien sûr, avoir besoin de l’ajuster à vos besoins précis.

/**
 * 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+$/, '')
}

Exemple d'utilisation:

> 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'

La fonction ci-dessus correspond à probablement ce que vous voulez utiliser pour éviter que les utilisateurs ne voient jamais les nombres saisis ayant été arrondis de manière incorrecte.

(Au lieu de cela, vous pouvez également essayer la bibliothèque round1 qui fournit une fonction ayant un comportement similaire avec une implémentation extrêmement différente.)

Mais que se passe-t-il si vous avez le deuxième type de nombre - une valeur prise sur une échelle continue, où il n’ya aucune raison de penser que les représentations décimales approximatives avec moins de décimales sont plus précis que celles avec plus? Dans ce cas, nous ne pas == voulons respecter la représentation String, car cette représentation (comme expliqué dans la spécification) est déjà en quelque sorte arrondie; nous ne voulons pas commettre l'erreur de dire "0,014999999 ... 375 arrondis à 0,015, ce qui arrondit à 0,02, donc 0,014999999 ... 375 arrondis à 0,02".

Ici, nous pouvons simplement utiliser la méthode intégrée toFixed . Notez qu'en appelant Number() sur la chaîne renvoyée par toFixed, nous obtenons un nombre dont la représentation de chaîne n'a pas de zéros à la fin (grâce à la manière dont JavaScript calcule la représentation sous forme de chaîne d'un nombre, décrite précédemment dans cette réponse).

/**
 * 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);
}
66
Mark Amery

Une méthode d'arrondissement précise. Source: 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);
        };
    }
})();

Exemples:

// 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
62
user

Aucune des réponses trouvées ici n'est correcte. @stinkycheeseman a demandé de arrondir, vous avez tous arrondi le nombre.

Pour arrondir, utilisez ceci:

Math.ceil(num * 100)/100;
58
machineaddict

Tu devrais utiliser:

_Math.round( num * 100 + Number.EPSILON ) / 100
_

Personne ne semble être au courant de Number.EPSILON .

En outre, il convient de noter que ce n'est pas un JavaScript étrange comme certaines personnes l'ont déclaré.

C’est simplement ainsi que fonctionnent les nombres à virgule flottante sur un ordinateur. Comme 99% des langages de programmation, JavaScript n’a pas fait maison nombres en virgule flottante; il s’appuie sur le CPU/FPU pour cela. Un ordinateur utilise binaire, et en binaire, il n'y a pas de nombres comme _0.1_, mais une simple approximation binaire pour cela. Pourquoi? Pour la même raison, 1/3 ne peut pas être écrit en décimal: sa valeur est 0.33333333 ... avec une infinité de trois.

Voici Number.EPSILON . Ce nombre est la différence entre 1 et le nombre suivant existant dans les nombres à virgule flottante double précision. C'est tout: il n'y a pas de nombre entre _1_ et 1 + _Number.EPSILON_.

EDIT:

Comme demandé dans les commentaires, clarifions une chose: l'ajout de _Number.EPSILON_ n'est pertinent que lorsque la valeur à arrondir est le résultat d'une opération arithmétique, car elle peut engloutir un delta d'erreur en virgule flottante.

Ce n'est pas utile lorsque la valeur provient d'une source directe (par exemple: littéral, entrée utilisateur ou capteur).

EDIT (2019):

Comme @maganap et certains peuples l'ont souligné, il est préférable d'ajouter Number.EPSILON avant de multiplier:

_Math.round( ( num + Number.EPSILON ) * 100 ) / 100
_
57
cronvel

Voici un moyen simple de le faire:

Math.round(value * 100) / 100

Vous voudrez peut-être aller de l'avant et créer une fonction distincte pour le faire pour vous cependant:

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

Ensuite, il vous suffirait de transmettre la valeur.

Vous pouvez l'améliorer pour arrondir à un nombre quelconque de décimales en ajoutant un deuxième paramètre.

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

    return (Math.round(value * multiplier) / multiplier);
}
45
JayDM

Pour moi Math.round () ne donnait pas de réponse correcte. J'ai trouvé toFixed (2) fonctionne mieux. Voici des exemples des deux:

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

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer
36
VicJordan
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
36
user3711536

Utilisez cette fonction Number(x).toFixed(2);

34
Harish.bazee

2017
Utilisez simplement du code natif .toFixed()

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

Si vous devez être strict et ajouter des chiffres au besoin, vous pouvez utiliser replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');
33
pery mimon

Essayez ceci poids léger solution:

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

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222
32
petermeissner

Il y a deux façons de le faire. Pour les gens comme moi, la variante de 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))
}

tilisation:

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

Si votre projet utilise jQuery ou lodash, vous pouvez également trouver la méthode round appropriée dans les bibliothèques.

Mise à jour 1

J'ai supprimé la variante n.toFixed(2), car elle n'est pas correcte. Merci @ avalanche1

28
stanleyxu2005

MarkG et Lavamantis ont proposé une solution bien meilleure que celle qui a été acceptée. C'est dommage qu'ils ne reçoivent pas plus de votes positifs!

Voici la fonction que j'utilise pour résoudre les problèmes de nombres décimaux à virgule flottante également basé sur MDN . C'est encore plus générique (mais moins concis) que la solution de 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));
}

Utilisez-le avec:

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

Par rapport à la solution de Lavamantis, nous pouvons faire ...

round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123
22
astorije

Si vous utilisez la bibliothèque lodash, vous pouvez utiliser la méthode round de lodash comme suit.

_.round(number, precision)

Par exemple:

_.round(1.7777777, 2) = 1.78
21
Madura Pradeep

Depuis ES6, il existe un moyen "approprié" (sans passer outre à la statique et sans créer de solution de contournement) pour le faire en avec 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));

alors vous pouvez simplement parseFloat et les zéros vont "disparaître".

console.log(parseFloat((1.4999).toPrecision(3)));
console.log(parseFloat((1.005).toPrecision(3)));
console.log(parseFloat((1.0051).toPrecision(3)));
19
Matas Vaitkevicius

Cela peut vous aider:

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

pour plus d'informations, vous pouvez consulter ce lien

Math.round (num) vs num.toFixed (0) et incohérences du navigateur

18
totten
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) ici 2 est le nombre de chiffres jusqu'à lequel nous voulons arrondir ce nombre.

16
Ritesh Dhuri

Cela peut fonctionner pour vous,

Math.round(num * 100)/100;

connaître la différence entre toFixed et round. Vous pouvez consulter Math.round (num) vs num.toFixed (0) et les incohérences du navigateur.

15
Shreedhar

Manière la plus simple:

+num.toFixed(2)

Il le convertit en chaîne, puis en un entier/float.

13
Edmund

Utilisez quelque chose comme ça "parseFloat (parseFloat (valeur) .toFixed (2))"

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1
13
Arulraj

Voici une méthode prototype:

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

var yournum = 10.55555;
yournum = yournum.round(2);
12
arielf

En général, l’arrondi se fait en mettant à l’échelle: round(num / p) * p

L'utilisation de la notation exponentielle gère correctement l'arrondi des nombres + v. Cependant, cette méthode ne parvient pas à arrondir correctement les cas Edge.

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

Voici également une fonction que j’ai écrite pour effectuer correctement les arrondis arithmétiques. Vous pouvez le tester vous-même.

/**
 * 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
11
Amr Ali

Pour ne pas traiter beaucoup de 0, utilisez cette variante:

Math.round(num * 1e2) / 1e2
10
Daniel De León

Si vous utilisez déjà la bibliothèque d3, ils disposent d’une puissante bibliothèque de formatage des nombres: https://github.com/mbostock/d3/wiki/Formatting

Arrondir spécifiquement est ici: https://github.com/mbostock/d3/wiki/Formatting#d3_round

Dans votre cas, la réponse est:

> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
9
Scott Stafford

Un moyen de réaliser un tel arrondi uniquement si nécessaire consiste à utiliser Number.prototype.toLocaleString () :

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

Cela fournira exactement le résultat attendu, mais sous forme de chaînes. Vous pouvez toujours les reconvertir en nombres si ce n'est pas le type de données attendu.

9
Javarome

Une façon plus simple de l’ES6 est de

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

Ce modèle renvoie également la précision demandée.

ex:

round(44.7826456, 4)  // yields 44.7826
round(78.12, 4)       // yields 78.1200
8
Adam A.

Une approche différente consiste à utiliser une bibliothèque. Pourquoi pas lodash:

const _ = require("lodash")
const roundedNumber = _.round(originalNumber, 2)
8
Carlos Lombardi

Une solution simple serait d'utiliser la fonction ceil de lodash si vous voulez arrondir ...

https://lodash.com/docs/4.17.10#ceil

_.round(6.001,2)

donne 6

_.ceil(6.001, 2);

donne 6.01

_.ceil(37.4929,2);

donne 37,5

_.round(37.4929,2);

donne 37,49

8
Jinxer Albatross

parseFloat ("1,555"). toFixed (2); // Retourne 1.55 au lieu de 1.56.

1.55 est le résultat correct absolu, car il n’existe pas de représentation exacte de 1.555 dans l’ordinateur. Si vous lisez 1.555, il est arrondi à la valeur la plus proche possible = 1.5549999999999999994 (float 64 bits). Et en arrondissant ce nombre à toFixed (2), on obtient 1,55.

Toutes les autres fonctions fournies ici donnent un résultat d'erreur si l'entrée est 1.55499999999999.

Solution: Ajoutez le chiffre "5" avant de numériser pour arrondir (le plus exact: arrondir à 0) le nombre. Ne faites cela que si le nombre est réellement un nombre à virgule flottante (avec un point décimal).

parseFloat("1.555"+"5").toFixed(2); // Returns 1.56
7
Wiimm

C'est la solution la plus simple et la plus élégante (et je suis la meilleure du monde;):

function roundToX(num, X) {    
    return +(Math.round(num + "e+"+X)  + "e-"+X);
}
//roundToX(66.66666666,2) => 66.67
//roundToX(10,2) => 10
//roundToX(10.904,2) => 10.9
7
Soldeplata Saketos

Je vais ajouter une autre approche à cela.

number = 16.6666666;
console.log(parseFloat(number.toFixed(2)));
"16.67"

number = 16.6;
console.log(parseFloat(number.toFixed(2)));
"16.6"

number = 16;
console.log(parseFloat(number.toFixed(2)));
"16"

.toFixed(2) renvoie une chaîne avec exactement 2 décimales, zéros ou non. Faire une parseFloat() éliminera les zéros à la fin.

7
Marcos Lima

Basé sur le réponse choisie et le commentaire voté sur la même question:

Math.round((num + 0.00001) * 100) / 100

Cela fonctionne pour ces deux exemples:

Math.round((1.005 + 0.00001) * 100) / 100

Math.round((1.0049 + 0.00001) * 100) / 100
7
Fellow Stranger

Après avoir parcouru diverses itérations de tous les moyens possibles pour obtenir une précision d'arrondi décimale précise, il est clair que la solution la plus précise et la plus efficace consiste à utiliser Number.EPSILON. Ceci fournit une vraie solution mathématique au problème de la précision mathématique en virgule flottante. Il peut être facilement rempli comme indiqué ci-dessous: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON pour prendre en charge tous les derniers IE utilisateurs (encore une fois, nous devrions peut-être arrêter de le faire).

Adapté de la solution fournie ici: https://stackoverflow.com/a/48850944/6910392

Une solution simple à intégrer qui fournit des arrondis décimaux, des revêtements de sol et des plafonds précis, avec une variable de précision optionnelle sans ajouter de bibliothèque.

var DecimalPrecision = (function(){
        if (Number.EPSILON === undefined) {
            Number.EPSILON = Math.pow(2, -52);
        }
        this.round = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.round((n + r) * o) / o;
        }
        this.ceil = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.ceil((n + r) * o) / o;
        }
        this.floor = function(n, p=2){
            let r = 0.5 * Number.EPSILON * n;
            let o = 1; while(p-- > 0) o *= 10;
            if(n < 0)
                o *= -1;
            return Math.floor((n + r) * o) / o;
        }
        return this;
    })();
    console.log(DecimalPrecision.round(1.005));
    console.log(DecimalPrecision.ceil(1.005));
    console.log(DecimalPrecision.floor(1.005));
    console.log(DecimalPrecision.round(1.0049999));
    console.log(DecimalPrecision.ceil(1.0049999));
    console.log(DecimalPrecision.floor(1.0049999));
    console.log(DecimalPrecision.round(2.175495134384,7));
    console.log(DecimalPrecision.round(2.1753543549,8));
    console.log(DecimalPrecision.round(2.1755465135353,4));
6
KFish

Conserver le type sous forme d’entier pour un tri ultérieur ou d’autres opérations mathématiques:

Math.round(1.7777777 * 100)/100

1,78

// Round up!
Math.ceil(1.7777777 * 100)/100 

1,78

// Round down!
Math.floor(1.7777777 * 100)/100

1,77

Ou convertir en chaîne:

(1.7777777).toFixed(2)

"1,77"

6
profimedica

Je sais qu'il y a beaucoup de réponses, mais la plupart ont des effets secondaires dans certains cas.

La solution la plus simple et la plus courte sans effets secondaires est la suivante:

Number((2.3456789).toFixed(2)) // 2.35

Il arrondit correctement et renvoie un nombre au lieu d'une chaîne

console.log(Number((2.345).toFixed(2)))  // 2.35
console.log(Number((2.344).toFixed(2)))  // 2.34
console.log(Number((2).toFixed(2)))      // 2
console.log(Number((-2).toFixed(2)))     // -2
console.log(Number((-2.345).toFixed(2))) // -2.35

console.log(Number((2.345678).toFixed(3))) // 2.346
6
Nicolo

Cela a fait le tour pour moi (TypeScript):

round(decimal: number, decimalPoints: number): number{
    let roundedValue = Math.round(decimal * Math.pow(10, decimalPoints)) / Math.pow(10, decimalPoints);

    console.log(`Rounded ${decimal} to ${roundedValue}`);
    return roundedValue;
}

// Sample output:
Rounded 18.339840000000436 to 18.34
Rounded 52.48283999999984 to 52.48
Rounded 57.24612000000036 to 57.25
Rounded 23.068320000000142 to 23.07
Rounded 7.792980000000398 to 7.79
Rounded 31.54157999999981 to 31.54
Rounded 36.79686000000004 to 36.8
Rounded 34.723080000000124 to 34.72
Rounded 8.4375 to 8.44
Rounded 15.666960000000074 to 15.67
Rounded 29.531279999999924 to 29.53
Rounded 8.277420000000006 to 8.28
5
Ross

Je construisais un tipCalculator simple et il y avait beaucoup de réponses ici qui semblaient compliquer excessivement le problème. J'ai donc trouvé que résumer le problème était le meilleur moyen de vraiment répondre à cette question.

si vous voulez créer un nombre décimal arrondi, appelez d’abord toFixed(# of decimal places you want to keep) puis enroulez-le dans un nombre ()

donc résultat final:

let amountDue = 286.44;
tip = Number((amountDue * 0.2).toFixed(2));
console.log(tip)  // 57.29 instead of 57.288
4
Denis S Dujota

Voici la réponse la plus courte et complète:

function round(num, decimals) {
        var n = Math.pow(10, decimals);
        return Math.round( (n * num).toFixed(decimals) )  / n;
};

Ceci prend également en charge le cas d’exemple 1.005 qui retournera 1.01.

4
momomo

Essayez d’utiliser le jQuery plug-in. Number :

var number = 19.8000000007;
var res = 1 * $.number(number, 2);
4
user3447070

Pour arrondir aux décimales pos (sans décimales), faites Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos)

var console = {
 log: function(s) {
  document.getElementById("console").innerHTML += s + "<br/>"
 }
}
var roundDecimals=function(num,pos) {
 return (Math.round(num * Math.pow(10,pos)) / Math.pow(10,pos) );
}
//https://en.wikipedia.org/wiki/Pi
var pi=3.14159265358979323846264338327950288419716939937510;
for(var i=2;i<15;i++) console.log("pi="+roundDecimals(pi,i));
for(var i=15;i>=0;--i) console.log("pi="+roundDecimals(pi,i));
<div id="console" />
3
loretoparisi

Voici une fonction que je suis venu faire pour "arrondir". J'ai utilisé le double Math.round pour compenser la multiplication inexacte de JavaScript, donc 1,005 sera correctement arrondi à 1,01.

function myRound(number, decimalplaces){
    if(decimalplaces > 0){
        var multiply1 = Math.pow(10,(decimalplaces + 4));
        var divide1 = Math.pow(10, decimalplaces);
        return Math.round(Math.round(number * multiply1)/10000 )/divide1;
    }
    if(decimalplaces < 0){
        var divide2 = Math.pow(10, Math.abs(decimalplaces));
        var multiply2 = Math.pow(10, Math.abs(decimalplaces));
        return Math.round(Math.round(number / divide2) * multiply2);
    }
    return Math.round(number);
}
3
Andrei

J'ai écrit les fonctions suivantes pour moi-même. Cela vous aidera peut-être aussi.

function float_exponent(number) {
    exponent = 1;
    while (number < 1.0) {
        exponent += 1
        number *= 10
    }
    return exponent;
}
function format_float(number, extra_precision) {
    precision = float_exponent(number) + (extra_precision || 0)
    return number.toFixed(precision).split(/\.?0+$/)[0]
}

Usage:

format_float(1.01); // 1
format_float(1.06); // 1.1
format_float(0.126); // 0.13
format_float(0.000189); // 0.00019

Pour vous cas:

format_float(10, 1); // 10
format_float(9.1, 1); // 9.1
format_float(1.77777, 1); // 1.78
3
vsvasya

Vous pouvez également remplacer la fonction Math.round pour effectuer l'arrondi correct, ajouter un paramètre pour les décimales et l'utiliser comme suit: Math.round (Nombre, Décimales). N'oubliez pas que cela remplace le composant intégré Math.round et lui donne une autre propriété que celle d'origine.

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

Ensuite, vous pouvez simplement l'utiliser comme ceci:

Math.round(1.005, 2);

https://jsfiddle.net/k5tpq3pd/3/

3
Arne H. Bitubekk

Cela a plutôt bien fonctionné pour moi lorsque je voulais toujours arrondir à une certaine décimale. La clé ici est que nous arrondirons toujours avec la fonction Math.ceil.

Vous pouvez sélectionner conditionnellement le plafond ou le sol si nécessaire.

     /**
     * Possibility to lose precision at large numbers
     * @param number
     * @returns Number number
     */
    var roundUpToNearestHundredth = function(number) {

        // Ensure that we use high precision Number
        number = Number(number);

        // Save the original number so when we extract the Hundredth decimal place we don't bit switch or lose precision
        var numberSave = Number(number.toFixed(0));

        // Remove the "integer" values off the top of the number
        number = number - numberSave;

        // Get the Hundredth decimal places
        number *= 100;

        // Ceil the decimals.  Therefore .15000001 will equal .151, etc.
        number = Math.ceil(number);

        // Put the decimals back into their correct spot
        number /= 100;

        // Add the "integer" back onto the number
        return number + numberSave;

    };

console.log(roundUpToNearestHundredth(6132423.1200000000001))
2
thecoolestname36

Une légère variation est si vous devez formater un montant en devise sous la forme d'un montant entier en devise ou d'un montant avec des fractions de devise.

Par exemple:

1 devrait produire $ 1

1.1 devrait produire $ 1.10

1.01 devrait générer $ 1.01

En supposant que le montant est un nombre:

const formatAmount = (amount) => amount % 1 === 0 ? amount : amount.toFixed(2);

Si montant n'est pas un nombre, utilisez parseFloat (montant) pour le convertir en nombre.

2
Ibraheem

A partir des réponses existantes, j'ai trouvé une autre solution qui semble bien fonctionner, qui fonctionne également en envoyant une chaîne et en éliminant les zéros de fin.

function roundToDecimal(string, decimals) {
    return parseFloat(parseFloat(string).toFixed(decimals));
}

Il ne prend pas en compte si vous envoyez un taureau .. comme "apa" cependant. Ou alors, il y aura probablement une erreur qui, à mon avis, est la bonne, de toute façon, il n’est jamais bon de cacher les erreurs qui devraient être corrigées (par la fonction appelante).

2
OZZIE

J'ai trouvé que cela fonctionne pour tous mes cas d'utilisation:

const round = (value, decimalPlaces = 0) => {
    const multiplier = Math.pow(10, decimalPlaces);
    return Math.round(value * multiplier + Number.EPSILON) / multiplier;
};

Gardez à l'esprit que c'est ES6. Un équivalent ES5. serait très facile à coder, donc je ne vais pas l'ajouter.

1
Rob Evans

Je voulais juste partager mon approche, basée sur les réponses mentionnées précédemment:

Créons une fonction qui arrondit une valeur numérique donnée à une quantité donnée de décimales:

function roundWDecimals(n, decimals) {
    if (!isNaN(parseFloat(n)) && isFinite(n)) {
        if (typeof(decimals) == typeof(undefined)) {
            decimals = 0;
        }
        var decimalPower = Math.pow(10, decimals);
        return Math.round(parseFloat(n) * decimalPower) / decimalPower;
    }
    return NaN;
}

Et introduisez une nouvelle méthode "ronde" pour le prototype de nombres:

Object.defineProperty(Number.prototype, 'round', {
    enumerable: false,
    value: function(decimals) {
        return roundWDecimals(this, decimals);
    }
});

Et vous pouvez le tester:

function roundWDecimals(n, decimals) {
    if (!isNaN(parseFloat(n)) && isFinite(n)) {
        if (typeof(decimals) == typeof(undefined)) {
            decimals = 0;
        }
        var decimalPower = Math.pow(10, decimals);
        return Math.round(parseFloat(n) * decimalPower) / decimalPower;
    }
    return NaN;
}
Object.defineProperty(Number.prototype, 'round', {
    enumerable: false,
    value: function(decimals) {
        return roundWDecimals(this, decimals);
    }
});

var roundables = [
    {num: 10, decimals: 2},
    {num: 1.7777777, decimals: 2},
    {num: 9.1, decimals: 2},
    {num: 55.55, decimals: 1},
    {num: 55.549, decimals: 1},
    {num: 55, decimals: 0},
    {num: 54.9, decimals: 0},
    {num: -55.55, decimals: 1},
    {num: -55.551, decimals: 1},
    {num: -55, decimals: 0},
    {num: 1.005, decimals: 2},
    {num: 1.005, decimals: 2},
    {num: 19.8000000007, decimals: 2},
  ],
  table = '<table border="1"><tr><th>Num</th><th>Decimals</th><th>Result</th></tr>';
$.each(roundables, function() {
  table +=
    '<tr>'+
      '<td>'+this.num+'</td>'+
      '<td>'+this.decimals+'</td>'+
      '<td>'+this.num.round(this.decimals)+'</td>'+
    '</tr>'
  ;
});
table += '</table>';
$('.results').append(table);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="results"></div>
1
Deele

Voici ma solution à ce problème:

function roundNumber(number, precision = 0) {
var num = number.toString().replace(",", "");
var integer, decimal, significantDigit;

if (num.indexOf(".") > 0 && num.substring(num.indexOf(".") + 1).length > precision && precision > 0) {
    integer = parseInt(num).toString();
    decimal = num.substring(num.indexOf(".") + 1);
    significantDigit = Number(decimal.substr(precision, 1));

    if (significantDigit >= 5) {
        decimal = (Number(decimal.substr(0, precision)) + 1).toString();
        return integer + "." + decimal;
    } else {
        decimal = (Number(decimal.substr(0, precision)) + 1).toString();
        return integer + "." + decimal;
    }
}
else if (num.indexOf(".") > 0) {
    integer = parseInt(num).toString();
    decimal = num.substring(num.indexOf(".") + 1);
    significantDigit = num.substring(num.length - 1, 1);

    if (significantDigit >= 5) {
        decimal = (Number(decimal) + 1).toString();
        return integer + "." + decimal;
    } else {            
        return integer + "." + decimal;
    }
} 

return number;
}
1
caliche2000

la question est à des tours de 2 décimales.

ne rendons pas cette chaîne de prototype de modification complexe compliquée, etc.

voici une solution en ligne

let round2dec = num => Math.round(num * 100) / 100; 

console.log(round2dec(1.77));
console.log(round2dec(1.774));
console.log(round2dec(1.777));
console.log(round2dec(10));
1
Salman

Pour mémoire, la méthode de mise à l'échelle pourrait théoriquement renvoyer Infinity si le nombre et les chiffres que vous souhaitez arrondir sont suffisamment grands. En JavaScript, cela ne devrait pas poser de problème puisque le nombre maximum est 1.7976931348623157e + 308, mais si vous travaillez avec des nombres très gros ou avec beaucoup de décimales, vous pouvez essayer cette fonction:

Number.prototype.roundTo = function(digits)
{
    var str = this.toString();
    var split = this.toString().split('e');
    var scientific = split.length > 1;
    var index;
    if (scientific)
    {
        str = split[0];
        var decimal = str.split('.');
        if (decimal.length < 2)
            return this;
        index = decimal[0].length + 1 + digits;
    }
    else
        index = Math.floor(this).toString().length + 1 + digits;
    if (str.length <= index)
        return this;
    var digit = str[index + 1];
    var num = Number.parseFloat(str.substring(0, index));
    if (digit >= 5)
    {
        var extra = Math.pow(10, -digits);
        return this < 0 ? num - extra : num + extra;
    }
    if (scientific)
        num += "e" + split[1];
    return num;
}
1
Martin

Le grand défi de cette tâche apparemment simple est que nous voulons qu’elle produise les résultats attendus sur le plan psychologique, même si l’entrée contient au minimum des erreurs d’arrondi (sans mentionner les erreurs qui se produiront dans notre calcul). Si nous savons que le résultat réel est exactement 1,005, nous nous attendons à ce que l’arrondi à deux chiffres donne 1,01, même si le 1,005 est le résultat d’un calcul volumineux avec beaucoup d’erreurs d’arrondi.

Le problème devient encore plus évident lorsqu'il s'agit de floor() au lieu de round(). Par exemple, quand on supprime tout après les deux derniers chiffres derrière le point de 33,3, on s’attend certainement pas à obtenir un résultat de 33,29, mais c'est ce qui se passe:

console.log(Math.floor(33.3 * 100) / 100)

Dans les cas simples, la solution consiste à effectuer des calculs sur des chaînes plutôt que des nombres à virgule flottante, afin d'éviter les erreurs d'arrondi. Cependant, cette option échoue à la première opération mathématique non triviale (y compris la plupart des divisions) et est lente.

Lorsque vous utilisez des nombres en virgule flottante, la solution consiste à introduire un paramètre indiquant le montant par lequel nous sommes disposés à dévier du résultat de calcul réel, afin de produire le résultat psychologiquement attendu.

var round = function(num, digits = 2, compensateErrors = 2) {
  if (num < 0) {
    return -this.round(-num, digits, compensateErrors);
  }
  const pow = Math.pow(10, digits);
  return (Math.round(num * pow * (1 + compensateErrors * Number.EPSILON)) / pow);
}

/* --- testing --- */

console.log("Edge cases mentioned in this thread:")
var values = [ 0.015, 1.005, 5.555, 156893.145, 362.42499999999995, 1.275, 1.27499, 1.2345678e+2, 2.175, 5.015, 58.9 * 0.15 ];
values.forEach((n) => {
  console.log(n + " -> " + round(n));
  console.log(-n + " -> " + round(-n));
});

console.log("\nFor numbers which are so large that rounding cannot be performed anyway within computation precision, only string-based computation can help.")
console.log("Standard: " + round(1e+19));
console.log("Compensation = 1: " + round(1e+19, 2, 1));
console.log("Effectively no compensation: " + round(1e+19, 2, 0.4));

Remarque: Internet Explorer ne connaît pas Number.EPSILON. Si vous êtes encore mal à l'aise de le supporter, vous pouvez utiliser une cale, ou simplement définir vous-même la constante pour cette famille de navigateurs spécifique.

1
malamut

Le problème d'arrondi peut être évité en utilisant des nombres représentés par une notation exponentielle.

public roundFinancial(amount: number, decimals: number) {
    return Number(Math.round(Number(`${amount}e${decimals}`)) + `e-${decimals}`);
}
1
Dmytro Medvid

Dans l'environnement de noeud, je viens d'utiliser le module roundTo :

const roundTo = require('round-to');
...
roundTo(123.4567, 2);

// 123.46
1
Simon Prickett

Cette réponse concerne plus la vitesse.

var precalculatedPrecisions = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10];

function round(num, _prec) {
    _precision = precalculatedPrecisions[_prec]
    return Math.round(num * _precision + 1e-14) / _precision ;
}

jsPerf à ce sujet.

1
aleha

Une réponse générique pour tous les navigateurs et précisions:

function round(num, places) {
      if(!places){
       return Math.round(num);
      }

      var val = Math.pow(10, places);
      return Math.round(num * val) / val;
}

round(num, 2);
1
RBZ

A partir de l'exemple proposé sur le precisionRound que j'ai trouvé sur MDN (cet événement pour 1.005 répétitions 1 et non pas 1.01), j’écris un custom precisionRound qui gère un nombre aléatoire précis et pour 1.005, il retourne 1.01.

C'est la fonction:

function precisionRound(number, precision)
{
  if(precision < 0)
  {
    var factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  }
  else
    return +(Math.round(number + "e+"+precision)  + "e-"+precision);
}

console.log(precisionRound(1234.5678, 1));  // output: 1234.6
console.log(precisionRound(1234.5678, -1)); // output: 1230
console.log(precisionRound(1.005, 2));      // output: 1.01
console.log(precisionRound(1.0005, 2));     // output: 1
console.log(precisionRound(1.0005, 3));     // output: 1.001
console.log(precisionRound(1.0005, 4));     // output: 1.0005

Pour TypeScript:

public static precisionRound(number: number, precision: number)
{
  if (precision < 0)
  {
    let factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  }
  else
    return +(Math.round(Number(number + "e+" + precision)) +
      "e-" + precision);
}
1
Marco Barbero

Node.js

Cela a fait le tour pour moi sur Node.js en quelques secondes:

npm install math

Source: http://mathjs.org/examples/basic_usage.js.html

0
nottinhill

S'il vous plaît utiliser la fonction ci-dessous si vous ne voulez pas arrondir.

function ConvertToDecimal(num) {
  num = num.toString(); // If it's not already a String
  num = num.slice(0, (num.indexOf(".")) + 3); // With 3 exposing the hundredths place    
alert('M : ' + Number(num)); // If you need it back as a Number     
}
0
Nimesh
number=(parseInt((number +0.005)*100))/100;     

ajoutez 0,005 si vous voulez un tour normal (2 décimales)

8.123 +0.005=> 8.128*100=>812/100=>8.12   

8.126 +0.005=> 8.131*100=>813/100=>8.13   
0
Elid Garazlic

J'ai créé cette fonction pour arrondir un nombre. La valeur peut être une chaîne (ex. '1.005') ou un nombre 1.005 qui sera 1 par défaut et si vous spécifiez la décimale à 2, le résultat sera 1.01

round(value: string | number, decimals: number | string = "0"): number | null {
    return +( Math.round(Number(value + "e+"+decimals)) + "e-" + decimals);
}

Usage: rond (1.005, 2) // 1.01 ou Usage: rond ('1.005', 2) //1.01

0
chriscrossweb

En utilisant la solution de Brian Ustas:

function roundDecimal(value, precision) {
    var multiplier = Math.pow(10, precision);
    return Math.round(value * multiplier) / multiplier;
}
0
Roman M

Fonction d'aide rapide où rounging est votre arrondi par défaut: let arrondi = 4;

let round=(number)=>{ let multiply=Math.pow(10,rounding);  return Math.round(number*multiply)/multiply};

console.log(round(0.040579431));

=> 0.0406