En JavaScript, lors de la conversion d'un float en chaîne, comment puis-je obtenir 2 chiffres après le point décimal? Par exemple, 0,34 au lieu de 0,3445434.
var result = Math.round(original*100)/100;
Les détails , au cas où le code ne serait pas explicite.
edit: ... ou utilisez simplement toFixed
, comme proposé par Tim Büthe . Oublié celui-là, merci (et un upvote) pour rappel :)
Il y a des fonctions pour arrondir les nombres. Par exemple:
var x = 5.0364342423;
print(x.toFixed(2));
imprimera 5.04.
EDIT: Violon
Soyez prudent lorsque vous utilisez toFixed()
:
Tout d'abord, arrondir le nombre est effectué à l'aide de la représentation binaire du nombre, ce qui peut entraîner un comportement inattendu. Par exemple
(0.595).toFixed(2) === '0.59'
au lieu de '0.6'
.
Deuxièmement, il y a un bogue IE avec toFixed()
. Dans IE (du moins jusqu'à la version 7, ne vérifie pas IE8), ce qui suit est vrai:
(0.9).toFixed(0) === '0'
Cela peut être une bonne idée de suivre la suggestion de kkyy ou d’utiliser une fonction personnalisée toFixed()
, par exemple
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
Un autre problème à prendre en compte est que toFixed()
peut produire des zéros inutiles à la fin du nombre. Par exemple:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
L'idée est de nettoyer la sortie en utilisant un RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Le RegExp
correspond aux zéros de fin (et éventuellement au point décimal) pour s’assurer qu’il convient également aux entiers.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make Nice rounding
Il y a un problème avec toutes ces solutions flottant autour de multiplicateurs. Les solutions de Kkyy et de Christoph sont malheureusement mauvaises.
Veuillez tester votre code pour le nombre 551.175 avec 2 décimales - il sera arrondi à 551.17 alors qu'il devrait l'être 551.18! Mais si vous testez pour ex. 451.175 ça ira - 451.18. Il est donc difficile de repérer cette erreur au premier abord.
Le problème est avec la multiplication: essayez 551.175 * 100 = 55117.49999999999 (ups!)
Donc, mon idée est de le traiter avec toFixed () avant d'utiliser Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
La clé ici, je suppose, est d’arrondir correctement d’abord, puis vous pouvez le convertir en chaîne.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All Edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Vous pouvez maintenant formater cette valeur en toute sécurité avec toFixed (p). Donc, avec votre cas spécifique:
roundOf(0.3445434, 2).toFixed(2); // 0.34
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
Il n'y a aucun moyen d'éviter des arrondis incohérents pour les prix avec x.xx5 comme valeur réelle en utilisant la multiplication ou la division. Si vous devez calculer des prix corrects côté client, vous devez conserver tous les montants en cents. Cela est dû à la nature de la représentation interne des valeurs numériques en JavaScript. Notez que Excel souffre des mêmes problèmes et que la plupart des gens ne remarquent pas les petites erreurs causées par ce phénomène. Si les erreurs peuvent s'accumuler chaque fois que vous additionnez un grand nombre de valeurs calculées, il existe toute une théorie autour de cela impliquant l'ordre des calculs et d'autres méthodes permettant de minimiser l'erreur dans le résultat final. Pour souligner les problèmes liés aux valeurs décimales, veuillez noter que 0,1 + 0,2 n’est pas exactement égal à 0,3 en JavaScript, tandis que 1 + 2 est égal à 3.
Si vous voulez une corde sans rond, vous pouvez utiliser ce RegEx (peut-être que ce n'est pas le moyen le plus efficace ... mais c'est vraiment facile)
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
Peut-être voudrez-vous aussi un séparateur décimal? Voici une fonction que je viens de créer:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
J'utilise ce code pour formater les floats. Il est basé sur toPrecision()
mais il supprime les zéros inutiles. Je serais heureux de recevoir des suggestions sur la façon de simplifier la regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Exemple d'utilisation:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"