Tronquer le nombre à deux décimales sans arrondir

Supposons que j’ai une valeur de 15.7784514, je veux l’afficher 15.77 sans arrondi.

var num = parseFloat(15.7784514); document.write(num.toFixed(1)+"
"); document.write(num.toFixed(2)+"
"); document.write(num.toFixed(3)+"
"); document.write(num.toFixed(10));

Résulte en –

 15.8 15.78 15.778 15.7784514000 

Comment puis-je afficher 15,77?

Convertissez le nombre en une chaîne, faites correspondre le nombre à la deuxième décimale:

 function calc(theform) { var num = theform.original.value, rounded = theform.rounded var with2Decimals = num.toSsortingng().match(/^-?\d+(?:\.\d{0,2})?/)[0] rounded.value = with2Decimals } 
 
Original number:
"Rounded" number:

Mise à jour 5 novembre 2016

Nouvelle réponse, toujours précise

 function toFixed(num, fixed) { var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?'); return num.toSsortingng().match(re)[0]; } 

Comme les calculs en virgule flottante en javascript comporteront toujours des cas limites, la solution précédente sera précise la plupart du temps, ce qui n’est pas suffisant. Il existe des solutions à ce num.toPrecision , comme num.toPrecision , BigDecimal.js et accounting.js . Cependant, je pense que la simple parsing de la chaîne sera la plus simple et la plus précise.

Basant la mise à jour sur la regex bien écrite de la réponse acceptée par @Gumbo, cette nouvelle fonction toFixed fonctionnera toujours comme prévu.


Ancienne réponse, pas toujours exacte.

Roulez votre propre fonction toFixed:

 function toFixed(num, fixed) { fixed = fixed || 0; fixed = Math.pow(10, fixed); return Math.floor(num * fixed) / fixed; } 

J’ai opté pour l’écrire plutôt pour supprimer manuellement le rest avec des chaînes afin de ne pas avoir à gérer les problèmes de maths associés aux nombres:

 num = num.toSsortingng(); //If it's not already a Ssortingng num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place Number(num); //If you need it back as a Number 

Cela vous donnera “15.77” avec num = 15.7784514;

ParseInt est plus rapide que Math.floor

 function floorFigure(figure, decimals){ if (!decimals) decimals = 2; var d = Math.pow(10,decimals); return (parseInt(figure*d)/d).toFixed(decimals); }; floorFigure(123.5999) => "123.59" floorFigure(123.5999, 3) => "123.599" 

Octobre 2017

Solution générale pour tronquer (sans arrondir) un nombre quelconque au n-ième chiffre décimal et le convertir en une chaîne avec exactement n chiffres décimaux, pour tout n≥0.

 function toFixedTrunc(value, n) { const v = value.toSsortingng().split('.'); if (n <= 0) return v[0]; let f = v[1] || ''; if (f.length > n) return `${v[0]}.${f.substr(0,n)}`; while (f.length < n) f += '0'; return `${v[0]}.${f}` } 

Voici quelques tests pour n = 2 (y compris celui demandé par OP):

 0 => 0.00 0.01 => 0.01 0.2372 => 0.23 0.5839 => 0.58 0.999 => 0.99 1 => 1.00 1.01 => 1.01 2 => 2.00 2.551 => 2.55 2.5 => 2.50 2.99999 => 2.99 4.27 => 4.27 15.7784514 => 15.77 123.5999 => 123.59 

Veuillez noter que même si cela fonctionne toujours , une approche purement numérique ne le serait pas. Par exemple, considérons la fonction suivante (ou toute autre fonction similaire):

 function toFixedTrunc(value, n) { const f = Math.pow(10, n); return (Math.trunc(value*f)/f).toFixed(n); } 

Bien que conceptuellement correct, cela échouerait avec certains nombres irrationnels, par exemple 4.27, en raison de la façon dont les nombres sont représentés en interne.

Ces solutions fonctionnent, mais pour moi, cela me semble inutilement compliqué. Personnellement, j’aime bien utiliser l’opérateur de module pour obtenir le rest d’une opération de division et le supprimer. En supposant que num = 15.7784514:

 num-=num%.01; 

Cela équivaut à dire num = num – (num% .01).

Les réponses ici ne m’ont pas aidé, il a continué à arrondir ou à me donner la mauvaise décimale.

ma solution convertit votre décimal en chaîne, extrait les caractères et retourne le tout en tant que nombre.

 function Dec2(num) { num = Ssortingng(num); if(num.indexOf('.') !== -1) { var numarr = num.split("."); if (numarr.length == 1) { return Number(num); } else { return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1)); } } else { return Number(num); } } Dec2(99); // 99 Dec2(99.9999999); // 99.99 Dec2(99.35154); // 99.35 Dec2(99.8); // 99.8 Dec2(10265.985475); // 10265.98 

Le code suivant fonctionne très bien pour moi:

 num.toSsortingng().match(/.\*\\..{0,2}|.\*/)[0]; 
 num = 19.66752 f = num.toFixed(3).slice(0,-1) alert(f) 

Cela retournera 19,66

Ma version pour les nombres positifs:

 function toFixed_norounding(n,p) { var result = n.toFixed(p); return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p); } 

Rapide, joli, évident.

J’ai corrigé en utilisant la méthode simple suivante

 var num = 15.7784514; Math.floor(num*100)/100; 

Les résultats seront 15,77

Vous voilà. Une réponse qui montre encore une autre façon de résoudre le problème:

 // For the sake of simplicity, here is a complete function: function truncate(numToBeTruncated, numOfDecimals) { var theNumber = numToBeTruncated.toSsortingng(); var pointIndex = theNumber.indexOf('.'); return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined)); } 

Notez l’utilisation de + avant l’expression finale. Cela consiste à convertir notre chaîne tronquée, en tranches, en type nombre.

J’espère que cela aide!

tronquer sans zéros

 function toTrunc(value,n){ return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n)); } 

ou

 function toTrunc(value,n){ x=(value.toSsortingng()+".0").split("."); return parseFloat(x[0]+"."+x[1].substr(0,n)); } 

tester:

 toTrunc(17.4532,2) //17.45 toTrunc(177.4532,1) //177.4 toTrunc(1.4532,1) //1.4 toTrunc(.4,2) //0.4 

tronquer avec des zéros

 function toTruncFixed(value,n){ return toTrunc(value,n).toFixed(n); } 

tester:

 toTrunc(17.4532,2) //17.45 toTrunc(177.4532,1) //177.4 toTrunc(1.4532,1) //1.4 toTrunc(.4,2) //0.40 

Simple faites ça

 number = parseInt(number * 100)/100; 

Roulez votre propre fonction toFixed : pour les valeurs positives, Math.floor fonctionne Math.floor .

 function toFixed(num, fixed) { fixed = fixed || 0; fixed = Math.pow(10, fixed); return Math.floor(num * fixed) / fixed; } 

Pour les valeurs négatives, Math.floor est arrondi aux valeurs. Vous pouvez donc utiliser Math.ceil place.

Exemple,

 Math.ceil(-15.778665 * 10000) / 10000 = -15.7786 Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong. 

La seconde solution de Gumbo, avec l’expression régulière, fonctionne mais est lente à cause de l’expression régulière. La première solution de Gumbo échoue dans certaines situations en raison d’une imprécision des nombres à virgule flottante. Voir le JSFiddle pour une démonstration et un benchmark. La seconde solution prend environ 1636 nanosecondes par appel sur mon système actuel, le processeur Intel Core i5-2500 à 3,30 GHz.

La solution que j’ai rédigée consiste à append une petite compensation pour prendre en charge l’imprécision en virgule flottante. Il est fondamentalement instantané, c’est-à-dire de l’ordre de la nanoseconde. J’ai cadencé 2 nanosecondes par appel mais les timers JavaScript ne sont pas très précises ou granulaires. Voici le violon JS et le code.

 function toFixedWithoutRounding (value, precision) { var factorError = Math.pow(10, 14); var factorTruncate = Math.pow(10, 14 - precision); var factorDecimal = Math.pow(10, precision); return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal; } var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100]; for (var i = 0; i < values.length; i++) { var value = values[i]; console.log(value + " --> " + toFixedWithoutRounding(value, 2)); } for (var i = 0; i < values.length; i++) { var value = values[i]; console.log(value + " --> " + toFixedWithoutRounding(value, 4)); } console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2)); // Benchmark var value = 1.13 * 100; var startTime = new Date(); var numRun = 1000000; var nanosecondsPerMilliseconds = 1000000; for (var run = 0; run < numRun; run++) toFixedWithoutRounding(value, 2); var endTime = new Date(); var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime); var timePerCallNs = timeDiffNs / numRun; console.log("Time per call (nanoseconds): " + timePerCallNs); 

J’ai utilisé (num-0.05).toFixed(1) pour obtenir le deuxième plancher décimal.

S’appuyant sur la réponse de David D :

 function NumberFormat(num,n) { var num = (arguments[0] != null) ? arguments[0] : 0; var n = (arguments[1] != null) ? arguments[1] : 2; if(num > 0){ num = Ssortingng(num); if(num.indexOf('.') !== -1) { var numarr = num.split("."); if (numarr.length > 1) { if(n > 0){ var temp = numarr[0] + "."; for(var i = 0; i < n; i++){ if(i < numarr[1].length){ temp += numarr[1].charAt(i); } } num = Number(temp); } } } } return Number(num); } console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2)); console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2)); console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2)); console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2)); console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2)); console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4)); console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8)); console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2)); console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2)); console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2)); console.log('NumberFormat("0",2)',NumberFormat("0",2)); console.log('NumberFormat("",2)',NumberFormat("",2)); console.log('NumberFormat(85156,8)',NumberFormat(85156,8)); console.log('NumberFormat("85156",2)',NumberFormat("85156",2)); console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2)); // NumberFormat(123.85,2) 123.85 // NumberFormat(123.851,2) 123.85 // NumberFormat(0.85,2) 0.85 // NumberFormat(0.851,2) 0.85 // NumberFormat(0.85156,2) 0.85 // NumberFormat(0.85156,4) 0.8515 // NumberFormat(0.85156,8) 0.85156 // NumberFormat(".85156",2) 0.85 // NumberFormat("0.85156",2) 0.85 // NumberFormat("1005.85156",2) 1005.85 // NumberFormat("0",2) 0 // NumberFormat("",2) 0 // NumberFormat(85156,8) 85156 // NumberFormat("85156",2) 85156 // NumberFormat("85156.",2) 85156 

Une autre solution sur une seule ligne:

 number = Math.trunc(number*100)/100 

J’ai utilisé 100 parce que vous voulez tronquer au deuxième chiffre, mais une solution plus flexible serait:

 number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits) 

où chiffres est la quantité de chiffres décimaux à conserver.

Il est plus fiable d’obtenir deux points flottants sans arrondir.

Réponse de référence

 var number = 10.5859; var fixed2FloatPoints = parseInt(number * 100) / 100; console.log(fixed2FloatPoints); 

Il existe déjà une réponse appropriée avec une expression régulière et un calcul arithmétique, vous pouvez également essayer ceci

 function myFunction() { var str = 12.234556; str = str.toSsortingng().split('.'); var res = str[1].slice(0, 2); document.getElementById("demo").innerHTML = str[0]+'.'+res; } // output: 12.23 

Voici ce qui est fait avec de la ficelle

 export function withoutRange(number) { const str = Ssortingng(number); const dotPosition = str.indexOf('.'); if (dotPosition > 0) { const length = str.subssortingng().length; const end = length > 3 ? 3 : length; return str.subssortingng(0, dotPosition + end); } return str; } 

Merci Martin Varmus

 function floorFigure(figure, decimals){ if (!decimals) decimals = 2; var d = Math.pow(10,decimals); return ((figure*d)/d).toFixed(decimals); }; floorFigure(123.5999) => "123.59" floorFigure(123.5999, 3) => "123.599" 

Je fais une mise à jour simple et j’ai obtenu un arrondi approprié. La mise à jour est la ligne suivante

 return ((figure*d)/d).toFixed(decimals); 

supprimer la fonction parseInt ()

Voici une autre variante pour enregistrer .toFixed ([chiffres]) fonctionnelle sans arrondi variable flottante:

 Number.prototype.toRealFixed = function(digits) { return Math.floor(this.valueOf() * Math.pow(10, digits)) / Math.pow(10, digits); }; 

Et appelant:

 var float_var = 0.02209062; float_var.toRealFixed();