Schneiden Sie die Zahl ohne Rundung auf zwei Dezimalstellen ab

194

Angenommen, ich habe einen Wert von 15.7784514 und möchte ihn mit 15.77 ohne Rundung anzeigen.

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

Ergebnisse in -

15.8
15.78
15.778
15.7784514000 

Wie zeige ich 15.77 an?

tempid
quelle
3
Ich bin versucht zu fragen, warum Sie keine Rundung wollen. Es scheint falsch, egal wo ...
Camilo Martin
38
Dies ist nützlich, wenn Sie eine Währung anzeigen.
Richard Ye
@ mik01aj - Bei der Anzeige von Währungen werden berechnete Werte häufiger abgeschnitten als gerundet. Beispielsweise kürzen die meisten Steuerformulare in den USA die berechneten Bruchteilscents eher als runde. In diesem Fall ist der abgeschnittene Wert der richtige Wert.
Steven Byks
4
@CamiloMartin gibt es einen großen Unterschied zwischen einer Verschuldung von 1,49 Milliarden Dollar und 1,0 Milliarden Dollar.
Broda Noel
3
Es gibt auch einen großen Unterschied zwischen 1,49 Milliarden und 1,50 Milliarden Dollar. Das sind 100 Millionen Dollar.
Liga

Antworten:

226

Konvertieren Sie die Zahl in eine Zeichenfolge und passen Sie die Zahl bis zur zweiten Dezimalstelle an:

function calc(theform) {
    var num = theform.original.value, rounded = theform.rounded
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
    rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>

Die toFixedMethode schlägt in einigen Fällen anders fehl toString, seien Sie also sehr vorsichtig damit.

Gumbo
quelle
22
+1 Damit sollte das Rundungsproblem gelöst sein. Ich würde das Ergebnis des oben genannten immer noch mit folgendem Ergebnis ausgeben toFixed: (Math.floor(value * 100) / 100).toFixed(2). Wie Sie wahrscheinlich wissen, können seltsame Dinge mit Gleitkommawerten passieren (und auf der anderen Seite des Spektrums, wenn die Zahl zufällig ist 15, klingt es so, wie es das OP will 15.00).
TJ Crowder
1
hehe, oder wenn Sie beide kombinieren:Number((15.7784514000*100).toString().match(/^\d+/)/100);
skobaljic
27
Math.floor (Wert * 100) / 100 funktioniert nicht, wenn der Wert = 4,27 ist. Probieren Sie es aus.
Dark Hippo
3
@DarkHippo Da 4.27 tatsächlich 4.26999999999 ist, ist Math.round im Allgemeinen eine bessere Lösung, wenn auch nicht die Antwort auf die ursprüngliche Frage. Wenn die Ausgabe realistisch gesehen eine Zeichenfolge ist, sollte dies mithilfe einer Zeichenfolgenmanipulation anstelle einer numerischen Lösung mit allen Gleitkomma-Schwächen erfolgen.
BJury
3
... das klingt nicht richtig. Das Konvertieren zwischen Typen scheint unter keinen Umständen umständlich und unsicher zu sein. Es sei denn, ein wirklich fortgeschrittener Programmierer würde argumentieren, dass "alle Typen nur Streams sind" oder so.
JackHasaKeyboard
66

Update 5. November 2016

Neue Antwort, immer genau

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

Da Gleitkomma-Mathematik in Javascript immer Randfälle hat, ist die vorherige Lösung die meiste Zeit genau, was nicht gut genug ist. Es gibt einige Lösungen für dieses wie num.toPrecision, BigDecimal.js und accounting.js . Ich glaube jedoch, dass das bloße Parsen der Zeichenfolge am einfachsten und immer genauesten ist.

Basierend auf dem gut geschriebenen regulären Ausdruck der akzeptierten Antwort von @Gumbo funktioniert diese neue toFixed-Funktion immer wie erwartet.


Alte Antwort, nicht immer richtig.

Rollen Sie Ihre eigene toFixed-Funktion:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}
Guya
quelle
7
toFixed (4,56, 2) = 4,55
Cryss
2
So viele dieser Antworten haben eine Multiplikation innerhalb einer Math.floor () -Funktion. Dies wird für einige Zahlen fehlschlagen! Gleitkomma-Arithmetik ist nicht genau und Sie müssen verschiedene Methoden verwenden.
Nico Westerdale
1
Funktion toFixedCustom (num, fest) {var re = new RegExp ('^ -? \\ d + (?: \. \\ d {0,' + (fest || -1) + '})?'); if (num.toString (). match (re)) {return num.toString (). match (re) [0]; }}
Ryan Augustine
1
Die aktualisierte Antwort schlägt für eine Zahl fehl, die groß oder klein genug ist, dass Javascript in wissenschaftlicher Notation dargestellt wird. toFixed(0.0000000052, 2)ergibt '5,2'. Dies kann behoben werden, indem return num.toFixed(fixed+1).match(re)[0];Sie "Ich verwende toFixed" mit einer Dezimalstelle über dem Ziel verwenden, um Rundungen zu vermeiden, und dann Ihr Regex-Match ausführen
Netherdan,
32

Ich habe mich dafür entschieden, dies stattdessen zu schreiben, um den Rest manuell mit Zeichenfolgen zu entfernen, damit ich mich nicht mit den mathematischen Problemen befassen muss, die mit Zahlen einhergehen:

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

Dies gibt Ihnen "15.77" mit num = 15.7784514;

ベ ン ノ ス ケ
quelle
5
Wenn Sie keine Dezimalstelle erzwingen, möchten Sie möglicherweise eine Bedingung hinzufügen, falls Sie auf ganze Zahlen stoßen. So: num = num.toString (); if (num.indexOf (".")> 0) {num = num.slice (0, (num.indexOf (".")) + 3)}; Nummer (num);
ケ ン ノ ス ケ
1
schön, wenn es Dezimalstellen hat, aber wenn es eine ganze Zahl ist, wird es fehlschlagen
Ruslan López
Wenn die Zahl 0,00000052 ist, dann ist es falsch, 5.2e
Vasanth
1
@Vasanth Wenn die Zahl 0,00000052 lautet, wird "0,00" zurückgegeben. Vielleicht wurde die Antwort seit
Drenai
Ja, es scheitert in
Randfällen
18

Oktober 2017

Allgemeine Lösung zum Abschneiden (keine Rundung) einer Zahl auf die n-te Dezimalstelle und zum Konvertieren in eine Zeichenfolge mit genau n Dezimalstellen für jedes n≥0.

function toFixedTrunc(x, n) {
  const v = (typeof x === 'string' ? x : x.toString()).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}`
}

Dabei kann x entweder eine Zahl (die in eine Zeichenfolge konvertiert wird) oder eine Zeichenfolge sein.

Hier sind einige Tests für n = 2 (einschließlich des von OP angeforderten):

0           => 0.00
0.01        => 0.01
0.5839      => 0.58
0.999       => 0.99
1.01        => 1.01
2           => 2.00
2.551       => 2.55
2.99999     => 2.99
4.27        => 4.27
15.7784514  => 15.77
123.5999    => 123.59
0.000000199 => 1.99 *

* Wie in der Anmerkung erwähnt, liegt dies an der impliziten Umwandlung von Javascript in Exponential für "1.99e-7" und für einige andere Werte von n:

15.001097   => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
SC1000
quelle
2
toFixedTrunc(0.000000199, 2) // 1.99
Maharramoff
1
@ShamkhalMaharramov: Wenn Sie die Entwicklungskonsole öffnen und 0,000000199 eingeben, was erhalten Sie? Sie erhalten 1.99e-7. Wenn Sie 0,000000199.toString () eingeben, was erhalten Sie dann? Sie erhalten "1.99e-7". Wenn Sie also 0.000000199 an die Funktion übergeben, wird "1.99e-7" und nicht "0.000000199" bearbeitet, und "korrekt" gibt "1.99" zurück. Siehe ecma-international.org/ecma-262/6.0/…
SC1000
13

parseInt ist schneller als 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"
Martin Varmus
quelle
2
es scheitert mit 1234567.89
Ruslan López
Könnten Sie Lopez näher erläutern?
Zardilior
3
floorFigure (4.56, 2) =
4.55
7

Mach das einfach

number = parseInt(number * 100)/100;
Imran Pollob
quelle
4
parseInt (8,2 * 100) = 819
VPaul
6
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)

Dies wird 19.66 zurückgeben

Alex Peng
quelle
5
(4.9999) .toFixed (3) .slice (0, -1) gibt 5,00 zurück, das erwartete Ergebnis ist 4,99.
Bruno Lemos
1
Ich empfehle stattdessen etwas wie .toFixed (6) .slice (0, -4) zu verwenden.
Bruno Lemos
Das ist perfekt, in meinem Fall ist es ok. Wenn ich zum Beispiel nur eine Dezimalzahl haben möchte, benutze num.toFixed (2) .slice (0, -1) (wenn num 1.2356 hat, gibt es 1.2 zurück)
Esteban Perez
5

Diese Lösungen funktionieren, scheinen mir aber unnötig kompliziert zu sein. Ich persönlich verwende gerne den Moduloperator, um den Rest einer Divisionsoperation zu erhalten und diesen zu entfernen. Angenommen, num = 15.7784514:

num-=num%.01;

Dies entspricht der Aussage von num = num - (num% .01).

jtrick
quelle
Das ist interessant, Nijkokun, danke, dass Sie darauf hingewiesen haben. Ich bin mit dieser Technik nie auf Probleme gestoßen, aber ich sollte mir solche Fälle genauer ansehen. Alternativ können Sie ((num * = 100) - (num% 1)) / 100 verwenden, um dieses Problem zu beheben. Die Priorität in meinem Fall ist die Ausführungsgeschwindigkeit aufgrund des Umfangs der Berechnungen, auf die ich dies anwende, und dies ist der schnellste Weg, dies zu erreichen, den ich gefunden habe.
Jtrick
1
Es ging darum, die in den anderen angebotenen Lösungen erforderlichen Objekt- und Funktionssuchen und -konvertierungen zu vermeiden. Danke für die Rückmeldung!
Jtrick
1
scheitert auch mit Negativen als -5
Ruslan López
Ich bin auch an einer schnellen Rundung interessiert. Wie würden Sie diesen Code dazu bringen, 1 Dezimalstelle zu machen?
thednp
5

Die Antworten hier haben mir nicht geholfen, sie haben sich immer wieder aufgerundet oder mir die falsche Dezimalstelle gegeben.

Meine Lösung konvertiert Ihre Dezimalstelle in eine Zeichenfolge, extrahiert die Zeichen und gibt dann das Ganze als Zahl zurück.

function Dec2(num) {
  num = String(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
David D.
quelle
Dec2 (99) sollte
99.00
5

Meine Version für positive Zahlen:

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

Schnell, hübsch, offensichtlich. (Version für positive Zahlen)

Alpha und omega
quelle
benötigte eine Nichtrundung für Float-Werte (z. B. Geld) mit nur 1 Dezimalstelle. Die obige Funktion sollte die "Antwort" dieses Themas sein, sie ist ausgezeichnet und funktioniert wie ein Zauber. Prost an den Autor & danke. :)))
Adrian Tanase
Fehlgeschlagen für negativen Wert. -0.7752. Test es toFixed_norounding(-0.7752,2)kehrt zurück -0.78statt-0.77
Ling Loeng
4

Der folgende Code funktioniert sehr gut für mich:

num.toString().match(/.\*\\..{0,2}|.\*/)[0];
MISSIRIA
quelle
Ich werde das optionale Minuszeichen hinzufügen, um es perfekt zu machen -?;)
Ruslan López
3

Ich habe das Problem auf folgende einfache Weise behoben:

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

Ergebnisse werden 15,77 sein

oms
quelle
Es funktioniert nicht mit negativen Werten: -15.7784514Rückkehr-15.78
Clément Baconnier
3

Schneiden Sie einfach die Ziffern ab:

function truncDigits(inputNumber, digits) {
  const fact = 10 ** digits;
  return Math.floor(inputNumber * fact) / fact;
}
Aral Roca
quelle
3

Eine weitere einzeilige Lösung:

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

Ich habe 100 verwendet, weil Sie auf die zweite Ziffer kürzen möchten, aber eine flexiblere Lösung wäre:

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

Dabei steht die Anzahl der Dezimalstellen, die beibehalten werden sollen.

Weitere Informationen und Browserkompatibilität finden Sie in den Math.trunc-Spezifikationen .

remidej
quelle
1
Dies ist die beste Antwort, wenn Sie IE11 nicht unterstützen müssen.
TJ.
2

Hier sind Sie ja. Eine Antwort, die einen weiteren Weg zur Lösung des Problems zeigt:

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

Beachten Sie die Verwendung von + vor dem endgültigen Ausdruck. Das heißt, unsere abgeschnittene, in Scheiben geschnittene Zeichenfolge wird wieder in den Zahlentyp konvertiert.

Ich hoffe es hilft!

Jakub Barczyk
quelle
1
Ich mag die Einfachheit dieses Ansatzes und bin der Meinung, dass alle Lösungen, die die Verwendung von Mathematik vermeiden, besser zur Lösung dieses Problems geeignet sind. Die Verwendung von Slice () usw. ist also der richtige Weg. Der einzige Vorteil meiner Methode ist, dass sie übergebene Zahlen verarbeitet, die Zeichenfolgen sind [umgeben von Anführungszeichen [einfach / doppelt]]. Aus irgendeinem Grund hat die obige Funktion einen Fehler in FF ausgelöst, als ich dies tat: console.log ('kürzen ("0.85156", 2)', kürzen ("0.85156", 2));
Charles Robertson
2

ohne Nullen abschneiden

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

oder

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

Prüfung:

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

mit Nullen abschneiden

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

Prüfung:

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

Das hat bei mir gut funktioniert. Ich hoffe, es wird auch Ihre Probleme beheben.

function toFixedNumber(number) {
    const spitedValues = String(number.toLocaleString()).split('.');
    let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
    decimalValue = decimalValue.concat('00').substr(0,2);

    return '$'+spitedValues[0] + '.' + decimalValue;
}

// 5.56789      ---->  $5.56
// 0.342        ---->  $0.34
// -10.3484534  ---->  $-10.34 
// 600          ---->  $600.00

function convertNumber(){
  var result = toFixedNumber(document.getElementById("valueText").value);
  document.getElementById("resultText").value = result;
}


function toFixedNumber(number) {
        const spitedValues = String(number.toLocaleString()).split('.');
        let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
        decimalValue = decimalValue.concat('00').substr(0,2);

        return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
  <input type="text" id="valueText" placeholder="Input value here..">
  <br>
  <button onclick="convertNumber()" >Convert</button>
  <br><hr>
  <input type="text" id="resultText" placeholder="result" readonly="true">
</div>

Sandaru
quelle
2

Ein einfacher Weg, dies zu tun, ist der nächste, aber es ist notwendig sicherzustellen, dass der Betragsparameter als Zeichenfolge angegeben wird.

function truncate(amountAsString, decimals = 2){
  var dotIndex = amountAsString.indexOf('.');
  var toTruncate = dotIndex !== -1  && ( amountAsString.length > dotIndex + decimals + 1);
  var approach = Math.pow(10, decimals);
  var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;  
  return toTruncate
    ?  Math.floor(parseFloat(amountToTruncate) * approach ) / approach
    :  parseFloat(amountAsString);

}}

console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Felipe Santa
quelle
2

function formatLimitDecimals(value, decimals) {
  value = value.toString().split('.')

  if (value.length === 2) {
    return Number([value[0], value[1].slice(0, decimals)].join('.'))
  } else {
    return Number(value[0]);
  }
}

console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4

Ruben Morales Felix
quelle
1

Früher (num-0.05).toFixed(1)habe ich die zweite Dezimalstelle erreicht.

王景飞
quelle
1

Meine Lösung in Typoskript (kann leicht auf JS portiert werden):

/**
 * Returns the price with correct precision as a string
 *
 * @param   price The price in decimal to be formatted.
 * @param   decimalPlaces The number of decimal places to use
 * @return  string The price in Decimal formatting.
 */
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
  price: number,
  decimalPlaces: number = 2,
): string => {
  const priceString: string = price.toString();
  const pointIndex: number = priceString.indexOf('.');

  // Return the integer part if decimalPlaces is 0
  if (decimalPlaces === 0) {
    return priceString.substr(0, pointIndex);
  }

  // Return value with 0s appended after decimal if the price is an integer
  if (pointIndex === -1) {
    const padZeroString: string = '0'.repeat(decimalPlaces);

    return `${priceString}.${padZeroString}`;
  }

  // If numbers after decimal are less than decimalPlaces, append with 0s
  const padZeroLen: number = priceString.length - pointIndex - 1;
  if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
    const padZeroString: string = '0'.repeat(padZeroLen);

    return `${priceString}${padZeroString}`;
  }

  return priceString.substr(0, pointIndex + decimalPlaces + 1);
};

Testfälle:

  expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
  expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
  expect(filters.toDecimalOdds(8.2)).toBe('8.20');

Irgendwelche Verbesserungen?

VPaul
quelle
0

Rollen Sie Ihre eigene toFixedFunktion: Für positive Werte Math.floorfunktioniert gut.

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

Bei negativen Werten Math.floorhandelt es sich um eine Runde der Werte. Sie können also Math.ceilstattdessen verwenden.

Beispiel,

Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Boopathi Sakthivel
quelle
5
So viele dieser Antworten haben eine Multiplikation innerhalb einer Math.floor () -Funktion. Dies wird für einige Zahlen fehlschlagen! Gleitkomma-Arithmetik ist nicht genau und Sie müssen verschiedene Methoden verwenden.
Nico Westerdale
0

Gumbos zweite Lösung mit dem regulären Ausdruck funktioniert zwar, ist aber aufgrund des regulären Ausdrucks langsam. Die erste Lösung von Gumbo schlägt in bestimmten Situationen aufgrund der Ungenauigkeit der Gleitkommazahlen fehl. In der JSFiddle finden Sie eine Demonstration und einen Benchmark. Die zweite Lösung benötigt auf meinem aktuellen System, der Intel Core i5-2500-CPU mit 3,30 GHz, ungefähr 1636 Nanosekunden pro Anruf.

Die Lösung, die ich geschrieben habe, besteht darin, eine kleine Kompensation hinzuzufügen, um Gleitkomma-Ungenauigkeiten zu beseitigen. Es ist im Grunde genommen augenblicklich, dh in der Größenordnung von Nanosekunden. Ich habe 2 Nanosekunden pro Aufruf getaktet, aber die JavaScript-Timer sind nicht sehr präzise oder detailliert. Hier ist die JS Fiddle und der 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);
Daniel Barbalace
quelle
0

Aufbauend auf der Antwort von 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 = String(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
Charles Robertson
quelle
0

Es ist zuverlässiger, zwei Gleitkommawerte ohne Rundung zu erhalten.

Referenzantwort

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

Danke !

Jaydeep Mor
quelle
0

Es gibt bereits einige passende Antworten mit regulären Ausdrücken und arithmetischen Berechnungen. Sie können dies auch versuchen

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

// output: 12.23
König Neo
quelle
0

Hier ist, was es mit String gemacht hat

export function withoutRange(number) {
  const str = String(number);
  const dotPosition = str.indexOf('.');
  if (dotPosition > 0) {
    const length = str.substring().length;
    const end = length > 3 ? 3 : length;
    return str.substring(0, dotPosition + end);
  }
  return str;
}
Kishan Vaghela
quelle
0

All diese Antworten scheinen etwas kompliziert zu sein. Ich würde nur 0,5 von Ihrer Zahl abziehen und toFixed () verwenden.

Sean Mayes
quelle
Du meintest 0,005?
Luan Nguyen
0

Die effizienteste Lösung (für 2 Bruchstellen) besteht darin, vor dem Aufruf 0,005 zu subtrahieren toFixed()

function toFixed2( num ) { return (num-0.005).toFixed(2) }

Negative Zahlen werden ebenfalls abgerundet (von Null weg). Das OP sagte nichts über negative Zahlen.

Wiimm
quelle
0

Ich weiß, dass es bereits wenige Arbeitsbeispiele gibt, aber ich denke, es lohnt sich, mein String.toFixed-Äquivalent vorzuschlagen. Einige mögen es hilfreich finden.

Das ist meine toFixed-Alternative, bei der Zahlen nicht gerundet, sondern nur abgeschnitten oder Nullen entsprechend der angegebenen Genauigkeit hinzugefügt werden. Für extra lange Zahlen wird die integrierte JS-Rundung verwendet, wenn die Genauigkeit zu lang ist. Die Funktion funktioniert für alle problematischen Nummern, die ich auf dem Stapel gefunden habe.

function toFixedFixed(value, precision = 0) {
    let stringValue = isNaN(+value) ? '0' : String(+value);

    if (stringValue.indexOf('e') > -1 || stringValue === 'Infinity' || stringValue === '-Infinity') {
        throw new Error('To large number to be processed');
    }

    let [ beforePoint, afterPoint ] = stringValue.indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];

    // Force automatic rounding for some long real numbers that ends with 99X, by converting it to string, cutting off last digit, then adding extra nines and casting it on number again
    // e.g. 2.0199999999999996: +('2.019999999999999' + '9999') will give 2.02
    if (stringValue.length >= 17 && afterPoint.length > 2 && +afterPoint.substr(afterPoint.length - 3) > 995) {
        stringValue = String(+(stringValue.substr(0, afterPoint.length - 1) + '9'.repeat(stringValue.split('.').shift().length + 4)));
        [ beforePoint, afterPoint ] = String(stringValue).indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];
    }

    if (precision === 0) {
        return beforePoint;
    } else if (afterPoint.length > precision) {
        return `${beforePoint}.${afterPoint.substr(0, precision)}`;
    } else {
        return `${beforePoint}.${afterPoint}${'0'.repeat(precision - afterPoint.length)}`;
    }
}

Beachten Sie, dass die Genauigkeit bei Zahlen mit einer Länge von 18 und mehr möglicherweise nicht richtig gehandhabt wird, z. B. wird 64-Bit-Chrome sie runden oder "e +" / "e-" hinzufügen, um die Länge der Zahl bei 18 zu halten.

Wenn Sie Operationen mit reellen Zahlen ausführen möchten, ist es sicherer, diese Math.sqrt(10, precision)zuerst zu multiplizieren , die Berechnungen durchzuführen und dann das Ergebnis mit dem Wert des Multiplikators zu tauchen.

Beispiel:

0.06 + 0.01ist 0.06999999999999999, und jede Formatierungsfunktion, die nicht rundet, schneidet sie ab0.06 Genauigkeit2 .

Wenn Sie jedoch dieselbe Operation mit Multiplikator und Teiler ausführen (0.06 * 100 + 0.01 * 100) / 100, erhalten Sie0.07 .

Aus diesem Grund ist es so wichtig, einen solchen Multiplikator / Teiler zu verwenden, wenn Sie mit reellen Zahlen in Javascript arbeiten, insbesondere wenn Sie Geld berechnen ...

MagyaDEV
quelle