Formattazione di un numero con esattamente due decimali in JavaScript


571

Ho questa riga di codice che arrotonda i miei numeri a due cifre decimali. Ma ottengo numeri come questo: 10,8, 2,4, ecc. Queste non sono la mia idea di due cifre decimali, quindi come posso migliorare quanto segue?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Voglio numeri come 10.80, 2.40, ecc. L'uso di jQuery va bene per me.


1
Il tuo codice è esattamente quello che stavo cercando (per ridurre la precisione del float a 7 decimali per file JSON più piccoli) Saltare Math.pow per speed val = Math.round (val * 10000000) / 10000000);
Pawel,

Come la risposta attualmente accettato dà senza dubbio un risultato sbagliato per una vasta gamma di valori grazie ad aggravare imprecisioni insita nei numeri ( 0.565, 0.575, 1.005), posso suggerire a guardare di nuovo in questa risposta , che ottiene correggerli?
TJ Crowder,

Forse vuoi includere una libreria sprintf per JavaScript stackoverflow.com/questions/610406/…
Thilo

Dopo aver arrotondato correttamente con il metodo di spostamento e arrotondamento della posizione decimale, è possibile utilizzare il number.toFixed(x)metodo per convertirlo in una stringa con la quantità richiesta di zero. Ad esempio rotonda 1.34per 1.3il metodo cross-browser quindi aggiungere 1 a zero e convertire in stringa con 1.3.toFixed(2)(per ottenere "1.30").
Edward,

Risposte:


999

Per formattare un numero usando la notazione a virgola fissa, puoi semplicemente usare il metodo toFixed :

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Si noti che toFixed()restituisce una stringa.

IMPORTANTE : si noti che toFixed non arrotonda il 90% delle volte, restituirà il valore arrotondato, ma per molti casi non funziona.

Per esempio:

2.005.toFixed(2) === "2.00"

AGGIORNARE:

Al giorno d'oggi, puoi usare il Intl.NumberFormatcostruttore. Fa parte della specifica API ECMAScript Internationalization (ECMA402). Ha il supporto del browser abbastanza buona , tra cui anche IE11, ed è pienamente supportato in Node.js .

const formatter = new Intl.NumberFormat('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

In alternativa puoi utilizzare il toLocaleStringmetodo, che internamente utilizzerà l' IntlAPI:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

Questa API offre anche un'ampia varietà di opzioni per la formattazione, come migliaia di separatori, simboli di valuta, ecc.


17
Non funziona in modo coerente su tutti i browser, vale a dire (0.09).toFixed(1);0,0 in IE8
ajbeaven

41
risolto non arrotondato, puoi prima farlo: (Math.round (0.09)). toFixed (1);
riapre il

32
@rekans: questo è sbagliato. Math.Round(0.09)tornerà 0quindi questo darà sempre 0.0...
Chris

28
Questa è una cattiva idea nella maggior parte dei casi, in alcuni casi converte il numero in una stringa o in un numero in virgola mobile.
Ash Blue,

80
Devi essere d'accordo con @AshBlue qui ... questo è sicuro solo per la formattazione della presentazione dei valori. Può rompere il codice con ulteriori calcoli. Altrimenti Math.round(value*100)/100funziona meglio per 2DP.
UpTheCreek

98

Questo è un vecchio argomento, ma i risultati di Google sono ancora al top e le soluzioni offerte condividono lo stesso problema con decimali in virgola mobile. Ecco la funzione (molto generica) che utilizzo, grazie a MDN :

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));
}

Come possiamo vedere, non abbiamo questi problemi:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Questa generalità fornisce anche alcune cose interessanti:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Ora, per rispondere alla domanda del PO, si deve digitare:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

Oppure, per una funzione più concisa, meno generica:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Puoi chiamarlo con:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Vari esempi e test (grazie a @ tj-crowder !):


1
Come non esiste un modo semplice per farlo? ES6 in soccorso?
zero_cool

Grazie per aver pubblicato il polyfill MDN. Nella pagina MDN collegata il polyfill non è più presente. Mi chiedo perché sia ​​stato rimosso ...
King Holly,

43

Di solito aggiungo questo alla mia libreria personale, e dopo alcuni suggerimenti e usando anche la soluzione @TIMINeutron, e rendendola adattabile per la lunghezza decimale, questa si adatta meglio:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

funzionerà per le eccezioni riportate.


2
precise_round (1.275,2) è 1,27?
Allenhwkim,

2
@Imre Modifica il valore restituito in (Math.round (num * Math.pow (10, decimali)) / Math.pow (10, decimali)). Su Fix (2); e non avrai più quel problema.
dkroy,

6
dove dichiarate "segno" e "dec" se la vostra seconda funzione viene raccolta come è, non dovrebbe averli come indefiniti?
Ady Ngom,

2
Ho aggiunto un workarround per il metodo del segno di errore in IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Armin,

1
@Armin La tua correzione la fa funzionare anche in Safari. La funzione originale non funzionava in Safari.
Dave,

19

Non so perché non posso aggiungere un commento a una risposta precedente (forse sono irrimediabilmente cieco, non so), ma ho trovato una soluzione usando la risposta di @ Miguel:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

E i suoi due commenti (da @bighostkim e @Imre):

  • Problema con precise_round(1.275,2)non ritorno 1.28
  • Problema con il precise_round(6,2)non ritorno alle 6.00 (come voleva).

La mia soluzione finale è la seguente:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Come puoi vedere, ho dovuto aggiungere un po 'di "correzione" (non è quello che è, ma poiché Math.round è in perdita - puoi controllarlo su jsfiddle.net - questo è l'unico modo in cui ho saputo come "risolvere "esso). Aggiunge 0,001 al numero già riempito, quindi aggiunge 1tre 0s a destra del valore decimale. Quindi dovrebbe essere sicuro da usare.

Dopodiché ho aggiunto .toFixed(decimal)di emettere sempre il numero nel formato corretto (con la giusta quantità di decimali).

Quindi è praticamente tutto. Usalo bene;)

EDIT: aggiunta funzionalità alla "correzione" di numeri negativi.


2
La "correzione" è per lo più sicura, ma ad esempio precise_round(1.27499,2)ora restituisce anche 1,28 ... Non è Math.roundche è perdita; il modo in cui i computer memorizzano internamente i valori in virgola mobile è. Fondamentalmente, sei destinato a fallire con alcuni valori prima ancora che i dati arrivino alla tua funzione :)
Imre

@Imre, hai assolutamente ragione. Ecco perché spiego cosa sta facendo questo 0.001, nel caso in cui qualcuno voglia renderlo "più preciso " o addirittura eliminarlo (se ti capita di avere un super computer con 2 Mbyte per float, che non credo che nessuno qui faccia ;)
tfrascaroli,

1
In realtà, la specifica della lingua è piuttosto specifica sull'uso di 64 bit per i valori numerici, quindi avere / usare un supercomputer non cambierebbe nulla :)
Imre

per 0,001 è possibile sostituire aggiungendo molti zeri in base alla lunghezza dei decimali. così ..
Miguel,

15

Un modo per essere sicuri al 100% di ottenere un numero con 2 decimali:

(Math.round(num*100)/100).toFixed(2)

Se ciò causa errori di arrotondamento, puoi utilizzare quanto segue come James ha spiegato nel suo commento:

(Math.round((num * 1000)/10)/100).toFixed(2)

6
Questo è il modo migliore e più semplice per farlo. Tuttavia, a causa della matematica in virgola mobile, 1.275 * 100 = 127.49999999999999, che potrebbe causare errori minori nell'arrotondamento. Per risolvere questo problema, possiamo moltiplicare per 1000 e dividere per 10, come (1.275 * 1000) / 10 = 127.5. Come segue: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould,

(Math.round ((1.015 * 1000) / 10) / 100) .toFixed (2) fornisce ancora 1,01, non dovrebbe essere 1.02?
gaurav5430,

14

toFixed (n) fornisce n lunghezza dopo il punto decimale; toPrecision (x) fornisce x lunghezza totale.

Utilizzare questo metodo di seguito

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

E se vuoi che il numero sia fisso, usa

result = num.toFixed(2);

non funziona bene ... per il numero num = 50.2349 dovresti scrivere a Precisione (3) per ottenere 50.2
Piotr Czyż

è solo un esempio puoi cambiarlo secondo le tue necessità @ PiotrCzyż
Syed Umar Ahmed

5

Non ho trovato una soluzione accurata per questo problema, quindi ho creato il mio:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Esempi:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57


2
Grazie. Eccone uno per testarlo: jsfiddle.net/lamarant/ySXuF . Sto applicando toFixed () al valore prima di restituirlo, che aggiunge il numero corretto di zero alla fine del valore restituito.
Lamarant,

non funziona per value = 0,004990845956707237 e inprecise_round (valore, 8) restituisce 0,00499085 ma deve tornare 0,00499084
MERT Dogan

3

@heridev e ho creato una piccola funzione in jQuery.

Puoi provare dopo:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO ONLINE:

http://jsfiddle.net/c4Wqn/


1
Posso apprezzare il contributo, anche se penso che l'aggiunta di elementi DOM e jQuery nel mix sembri al di fuori dell'ambito della domanda.
Chris,

Non dovresti ascoltare l'evento keyup, poiché sembra molto cattivo e non si attiva quando aggiungi qualcosa con lo script. Preferirei ascoltare l' inputevento. Questo non crea un effetto tremolante e si attiva anche quando si accede al campo con JS
Le 'nton,

3

Il problema con i valori in virgola mobile è che stanno cercando di rappresentare una quantità infinita di valori (continui) con una quantità fissa di bit. Quindi, naturalmente, ci deve essere qualche perdita in gioco e ti verrà morso con alcuni valori.

Quando un computer memorizza 1.275 come valore in virgola mobile, in realtà non ricorderà se fosse 1.275 o 1.27499999999999993, o anche 1.27500000000000002. Questi valori dovrebbero dare risultati diversi dopo l'arrotondamento a due decimali, ma non lo faranno, poiché per i computer sembrano esattamente gli stessi dopo essere stati archiviati come valori in virgola mobile e non c'è modo di ripristinare i dati persi. Ulteriori calcoli accumuleranno solo tale imprecisione.

Quindi, se la precisione conta, devi evitare i valori in virgola mobile dall'inizio. Le opzioni più semplici sono

  • usare una biblioteca dedicata
  • usa le stringhe per memorizzare e passare i valori (accompagnato da operazioni sulle stringhe)
  • usa numeri interi (ad es. potresti passare intorno alla quantità di centesimi del tuo valore reale, ad es. importo in centesimi anziché importo in dollari)

Ad esempio, quando si utilizzano numeri interi per memorizzare il numero di centesimi, la funzione per trovare il valore effettivo è abbastanza semplice:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Con le stringhe, dovrai arrotondare, ma è comunque gestibile:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Si noti che questa funzione viene arrotondata al più vicino, si lega da zero , mentre IEEE 754 consiglia di arrotondare al più vicino, si lega anche al comportamento predefinito per le operazioni in virgola mobile. Tali modifiche sono lasciate come esercizio per il lettore :)


3

Eccone uno semplice

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Usa come alert(roundFloat(1.79209243929,4));

Jsfiddle


2

Arrotondare il valore decimale, quindi utilizzare toFixed(x)per le cifre previste.

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Chiamata

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81


2

Arrotondare

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

Arrotondare

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Round più vicino

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Fuse https://stackoverflow.com/a/7641824/1889449 e https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Grazie.


2

/**
 * 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 +ve 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

// testing some -ve 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


2

Ecco la mia soluzione a 1 riga: Number((yourNumericValueHere).toFixed(2));

Ecco cosa succede:

1) Innanzitutto, si applica .toFixed(2)al numero di cui si desidera arrotondare le cifre decimali. Nota che questo convertirà il valore in una stringa dal numero. Quindi se stai usando Typescript, genererà un errore come questo:

"Digitare 'stringa' non è assegnabile per digitare 'numero'"

2) Per ripristinare il valore numerico o convertire la stringa in valore numerico, è sufficiente applicare la Number()funzione su quel cosiddetto valore 'stringa'.

Per chiarimenti, guarda l'esempio seguente:

ESEMPIO: Ho un importo che ha un massimo di 5 cifre nelle cifre decimali e vorrei accorciarlo fino a 2 cifre decimali. Lo faccio così:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);


1

Inserisci quanto segue in un ambito globale:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

e quindi prova :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Aggiornare

Si noti che toFixed()può funzionare solo per il numero di decimali tra 0-20ie a.getDecimals(25)può generare un errore javascript, quindi per accomodarsi è possibile aggiungere qualche controllo aggiuntivo es

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}

1
Number(((Math.random() * 100) + 1).toFixed(2))

questo restituirà un numero casuale da 1 a 100 arrotondato a 2 decimali.



1

Utilizzando questa risposta per riferimento: https://stackoverflow.com/a/21029698/454827

Costruisco una funzione per ottenere numeri dinamici di decimali:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

qui esempio funzionante: https://jsfiddle.net/wpxLduLc/


1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>


1

Con questi esempi continuerai ad avere un errore quando provi ad arrotondare il numero 1.005 la soluzione è usare una libreria come Math.js o questa funzione:

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

1

Ho avuto alcune idee da questo post qualche mese fa, ma nessuna delle risposte qui, né le risposte di altri post / blog sono state in grado di gestire tutti gli scenari (ad esempio numeri negativi e alcuni "numeri fortunati" trovati dal nostro tester). Alla fine, il nostro tester non ha riscontrato alcun problema con questo metodo di seguito. Incollare uno snippet del mio codice:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

Ho anche commenti in codice (scusate ho già dimenticato tutti i dettagli) ... Sto postando la mia risposta qui per riferimento futuro:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).

0

Sto risolvendo il problema con il modificatore. Supporta solo 2 decimali.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>


0
(Math.round((10.2)*100)/100).toFixed(2)

Ciò dovrebbe produrre: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Ciò dovrebbe produrre: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Ciò dovrebbe produrre: 4.04

eccetera.


0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/


0

Questo è molto semplice e funziona allo stesso modo di tutti gli altri:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Dal momento che toFixed () può essere chiamato solo sui numeri e purtroppo restituisce una stringa, questo fa tutto l'analisi per te in entrambe le direzioni. Puoi passare una stringa o un numero e ricevi un numero ogni volta! Chiamare parseNumber (1.49) ti darà 1, e parseNumber (1.49,2) ti darà 1.50. Proprio come il migliore di loro!


0

È inoltre possibile utilizzare il .toPrecision()metodo e un po 'di codice personalizzato e arrotondare sempre all'ennesima cifra decimale indipendentemente dalla lunghezza della parte int.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

Potresti anche renderlo un plugin per un uso migliore.



-2

Ho trovato un modo molto semplice che ha risolto questo problema per me e può essere utilizzato o adattato:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

-4

100% funzionante !!! Provalo

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>


Benvenuti in SO. Si prega di leggere questo how-to-risposta e seguire la linea guida alla risposta.
thewaywewere
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.