Wie runde ich Float-Zahlen in Javascript?

298

Ich muß Runde zum Beispiel 6.688689zu 6.7, aber es zeigt mir immer 7.

Meine Methode:

Math.round(6.688689);
//or
Math.round(6.688689, 1);
//or 
Math.round(6.688689, 2);

Aber das Ergebnis ist immer das gleiche 7... Was mache ich falsch?

Vitalii Ponomar
quelle
28
(6.688689​).toFixed(1);
Schatten-Assistent ist Ohr für Sie
Überprüfen Sie dies
raina77ow
Mögliches Duplikat der runden Zahl in JavaScript mit N Dezimalstellen - Bitte verwenden Sie die Suche, bevor Sie eine neue Frage stellen.
Felix Kling
1
@ShadowWizard ist korrekt. Allerdings .toFixedgibt einen String zurück. Stellen Sie sicher, dass Sie das Ergebnis einpacken Number(). Siehe akzeptierte Antwort und andere.
Jordan Arseno

Antworten:

534
Number((6.688689).toFixed(1)); // 6.7
David
quelle
22
Eine Zahl in eine Zeichenfolge umwandeln und dann wieder zurück? Das kann nicht schnell gehen.
CSL
Nicht gut, wenn Ihre Nummer weniger Dezimalstellen als benötigt hat. Es fügt einige hinzu
njzk2
2
Wie der JS-Benchmark zeigt, ist er langsamer als die Methode
@fivedigit
13
Number((456.1235).toFixed(3)) -> 456.123, Number((1.235).toFixed(2)) -> 1.24... Dummes JavaSript ...
NoOne
6
Dies könnte nicht das tun, was Sie erwarten! Das Ergebnis kann sogar vom Browser abhängen, siehe folgende Frage: stackoverflow.com/q/566564/2224996
maja
199
var number = 6.688689;
var roundedNumber = Math.round(number * 10) / 10;
fünfstellig
quelle
13
Das funktioniert nicht immer. Nehmen Sie Math.round(1.005*100)/100zum Beispiel von MDN
tybro0103
7
@ tybro0103 Gleitkomma böse: 1.005 * 100 = 100.49999999999999(zumindest in der JS-Engine, die ich versucht habe). Das ist der Grund, warum es nicht funktioniert und warum Sie sich niemals darauf verlassen sollten, dass Schwimmer perfekt genau sind.
Sudo
1
Falsch. Math.round (1.015 * 100) / 100 gibt 1.01 statt 1.02 zurück
Marco Marsala
81

Verwenden Sie toFixed()Funktion.

(6.688689).toFixed(); // equal to 7
(6.688689).toFixed(1); // equal to 6.7
(6.688689).toFixed(2); // equal to 6.69
rpeshkov
quelle
5
Dies könnte nicht das tun, was Sie erwarten! Das Ergebnis kann sogar vom Browser abhängen, siehe folgende Frage: stackoverflow.com/q/566564/2224996
maja
9
(6.688689) .toFixed (); ist gleich "7" nicht 7. Gleiches gilt für andere Beispiele.
Vado
35

Upd (2019-10). Dank des folgenden Codes von Reece Daniels ist er jetzt als eine Reihe von Funktionen verfügbar, die im erwarteten npm-Paket enthalten sind (siehe).


Sie können die Hilfsfunktion aus dem MDN-Beispiel verwenden . Dann haben Sie mehr Flexibilität:

Math.round10(5.25, 0);  // 5
Math.round10(5.25, -1); // 5.3
Math.round10(5.25, -2); // 5.25
Math.round10(5, 0);     // 5
Math.round10(5, -1);    // 5
Math.round10(5, -2);    // 5

Upd (15.01.2019). Scheint, als hätten MDN-Dokumente diese Helferfunktionen nicht mehr. Hier ist ein Backup mit Beispielen:

// Closure
(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;
    }
    // If the value is negative...
    if (value < 0) {
      return -decimalAdjust(type, -value, exp);
    }
    // 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);
    };
  }
})();

Anwendungsbeispiele:

// 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
Math.round10(-1.005, -2);  // -1.01
// 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
aspanchenko
quelle
2
?? "Math.round10 ist keine Funktion"
Peter Krauss
1
Ich fand das äußerst nützlich, also habe ich es in ein schnelles npm-Paket für diejenigen gesteckt, die es verwenden möchten, ohne zusätzlichen Code aufzublähen. Gutgeschrieben @aspanchenko mit der ursprünglichen Antwort auch: npmjs.com/package/expected-round
Reece Daniels
19
> +(6.688687).toPrecision(2)
6.7

Ein NumberObjekt in JavaScript verfügt über eine Methode, die genau das tut, was Sie benötigen. Diese Methode ist Number.toPrecision([precision]).

Genau wie bei der .toFixed(1)Konvertierung wird das Ergebnis in eine Zeichenfolge konvertiert und muss wieder in eine Zahl konvertiert werden. Fertig mit dem +Präfix hier.

einfacher Benchmark auf meinem Laptop:

number = 25.645234 typeof number
50000000 x number.toFixed(1) = 25.6 typeof string / 17527ms
50000000 x +(number.toFixed(1)) = 25.6 typeof number / 23764ms
50000000 x number.toPrecision(3) = 25.6 typeof string / 10100ms
50000000 x +(number.toPrecision(3)) = 25.6 typeof number / 18492ms
50000000 x Math.round(number*10)/10 = 25.6 typeof number / 58ms
string = 25.645234 typeof string
50000000 x Math.round(string*10)/10 = 25.6 typeof number / 7109ms
Evgeny
quelle
Meiner Meinung nach ist dies die beste Antwort (am besten in Bezug auf bewährte Verfahren, einfachster Ansatz).
Cezar
1
1e-10.toPrecision(3): "1.00e-10" - Dies rundet auf signifikante Ziffern .
Vsevolod Golovanov
9

Wenn Sie nicht nur, toFixed()sondern auch ceil()und floor()auf einem Float verwenden möchten, können Sie die folgende Funktion verwenden:

function roundUsing(func, number, prec) {
    var tempnumber = number * Math.pow(10, prec);
    tempnumber = func(tempnumber);
    return tempnumber / Math.pow(10, prec);
}

Produziert:

> roundUsing(Math.floor, 0.99999999, 3)
0.999
> roundUsing(Math.ceil, 0.1111111, 3)
0.112

UPD:

Der andere mögliche Weg ist folgender:

Number.prototype.roundUsing = function(func, prec){
    var temp = this * Math.pow(10, prec)
    temp = func(temp);
    return temp / Math.pow(10, prec)
}

Produziert:

> 6.688689.roundUsing(Math.ceil, 1)
6.7
> 6.688689.roundUsing(Math.round, 1)
6.7
> 6.688689.roundUsing(Math.floor, 1)
6.6
Dennis Yarmosh
quelle
Wie entscheiden wir dann, wann Decke, Boden oder Rundung zum Runden verwendet werden sollen? Zum Beispiel: roundUsing (Math.round, 1.015, 2) roundUsing (Math.ceil, 1.015, 2) geben 2 verschiedene Werte an. Woher wissen wir, welche wir verwenden sollen
gaurav5430
7

Meine erweiterte runde Funktion:

function round(value, precision) {
  if (Number.isInteger(precision)) {
    var shift = Math.pow(10, precision);
    // Limited preventing decimal issue
    return (Math.round( value * shift + 0.00000000000001 ) / shift);
  } else {
    return Math.round(value);
  }
} 

Beispielausgabe:

round(123.688689)     // 123
round(123.688689, 0)  // 123
round(123.688689, 1)  // 123.7
round(123.688689, 2)  // 123.69
round(123.688689, -2) // 100
round(1.015, 2) // 1.02
Nick Tsai
quelle
1
Dies ähnelt der Antwort von @ fivedigit. Runde (1.015, 2) gibt immer noch 1.01 statt 1.02
gaurav5430
@ gaurav5430, danke für deinen Bericht, ich habe es behoben.
Nick Tsai
6

Siehe unten

var original = 28.59;

var result=Math.round(original*10)/10 wird zurückkehren Sie kehrt zurück 28.6

Hoffe das ist was du willst ..

Fahim Parkar
quelle
7
"Wenn ich für jedes Mal einen Cent hätte, wenn ich jemanden gesehen hätte, der FLOAT zum Speichern von Währungen verwendet, hätte ich 999,997634 $" - Bill Karwin.
Emix
2
Falsch. Math.round (1.015 * 100) / 100
Marco Marsala
3
float(value,ndec);
function float(num,x){
this.num=num;
this.x=x;
var p=Math.pow(10,this.x);
return (Math.round((this.num).toFixed(this.x)*p))/p;
}
Celestin Sv
quelle
2

Ich denke, diese Funktion kann helfen.

 function round(value, ndec){
    var n = 10;
    for(var i = 1; i < ndec; i++){
        n *=10;
    }

    if(!ndec || ndec <= 0)
        return Math.round(value);
    else
        return Math.round(value * n) / n;
}


round(2.245, 2) //2.25
round(2.245, 0) //2
Jefferson Ribeiro
quelle
Ähnlich wie bei einigen anderen Antworten schlägt dies für die Runde (1.015, 2) fehl, die 1.02
gaurav5430
1

Ich denke unten Funktion kann helfen

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

Verwendung: roundOff(600.23458,2);wird zurückkehren600.23

KRISHNA TEJA
quelle
Können Sie erklären, was diese Antwort hinzufügt, die in den vorherigen Antworten noch nicht behandelt wurde?
Stealththeninja
Ähnlich wie bei einigen anderen Antworten schlägt dies für die Runde (1.015, 2) fehl, die 1.02
gaurav5430
1

Wenn Sie sich im Kontext von node.js befinden, können Sie mathjs ausprobieren

const math = require('mathjs')
math.round(3.1415926, 2) 
// result: 3.14
Hexcola
quelle
1

Es gibt die Alternative .toLocaleString () zum Formatieren von Zahlen mit vielen Optionen in Bezug auf Gebietsschemas, Gruppierung, Währungsformatierung und Notationen. Einige Beispiele:

Auf 1 Dezimalstelle runden, einen Float zurückgeben:

const n = +6.688689.toLocaleString('fullwide', {maximumFractionDigits:1})
console.log(
  n, typeof n
)

Auf 2 Dezimalstellen runden, als Währung mit angegebenem Symbol formatieren , Kommagruppierung für Tausende verwenden:

console.log(
  68766.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'currency', currency:'USD', useGrouping:true})   
)

Format als Länderwährung :

console.log(
  68766.688689.toLocaleString('fr-FR', {maximumFractionDigits:2, style:'currency', currency:'EUR'})   
)

Auf mindestens 3 Dezimalstellen runden, Nullen zur Anzeige zwingen:

console.log(
  6.000000.toLocaleString('fullwide', {minimumFractionDigits:3})
)

Prozentstil für Verhältnisse. Geben Sie * 100 mit% -Zeichen ein

console.log(
  6.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'percent'})
)

NVRM
quelle
1
+((6.688689 * (1 + Number.EPSILON)).toFixed(1)); // 6.7
+((456.1235 * (1 + Number.EPSILON)).toFixed(3)); // 456.124
Thanh Nguyễn Chí
quelle
1

Ich habe eine sehr gute Lösung, wenn toFixed () nicht funktioniert.

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

Beispiel

roundOff(10.456,2) //output 10.46
Ashish Gondaliya
quelle
0

Wenn Sie heute Browserify verwenden, müssen Sie Folgendes versuchen: roundTo eine sehr nützliche NPM- Bibliothek

Peterb
quelle
0

Kleinere Änderungen an dieser Antwort :

function roundToStep(value, stepParam) {
   var step = stepParam || 1.0;
   var inv = 1.0 / step;
   return Math.round(value * inv) / inv;
}

roundToStep(2.55, 0.1) = 2.6
roundToStep(2.55, 0.01) = 2.55
roundToStep(2, 0.01) = 2
Crashalot
quelle
roundToStep (1.015, 0.002) ergibt 1.014. ist, dass die richtige Art, es zu verwenden
gaurav5430
@ gaurav5430 versuchenroundToStep(1.015, 0.001)
Crashalot