Matematica JavaScript, intorno ai due decimali

Ho la seguente syntax JavaScript:

var discount = Math.round(100 - (price / listprice) * 100); 

Arrotonda l’intero numero, come posso restituire il risultato con due cifre decimali?

NOTA – Vedi Modifica 4 se la precisione a 3 cifre è importante

 var discount = (price / listprice).toFixed(2); 

toFixed arrotonda o abbassa per te in base ai valori oltre i 2 decimali.

Esempio: http://jsfiddle.net/calder12/tv9HY/

Documentazione: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Modifica – Come menzionato da altri, converte il risultato in una stringa. Per evitare questo:

 var discount = +((price / listprice).toFixed(2)); 

Modifica 2 – Come accennato anche nei commenti questa funzione fallisce con una certa precisione, nel caso di 1.005 per esempio restituirà 1.00 invece di 1.01. Se la precisione a questo livello è importante, ho trovato questa risposta: https://stackoverflow.com/a/32605063/1726511 Che sembra funzionare bene con tutti i test che ho provato.

Tuttavia, è necessaria una modifica minore, la funzione nella risposta collegata sopra restituisce numeri interi quando arrotonda a uno, quindi ad esempio 99,004 restituirà 99 invece di 99,00, che non è l’ideale per la visualizzazione dei prezzi.

Modifica 3 – Sembra che avere il toFixed sul rendimento effettivo è stato ANCORA rovinando alcuni numeri, questa modifica finale sembra funzionare. Accidenti così tante rielaborazioni!

  var discount = roundTo((price / listprice), 2); function roundTo(n, digits) { if (digits === undefined) { digits = 0; } var multiplicator = Math.pow(10, digits); n = parseFloat((n * multiplicator).toFixed(11)); var test =(Math.round(n) / multiplicator); return +(test.toFixed(digits)); } 

Guarda l’esempio di Fiddle qui: https://jsfiddle.net/calder12/3Lbhfy5s/

Modifica 4 – Ragazzi mi stanno uccidendo. La modifica 3 fallisce sui numeri negativi, senza scavare nel motivo per cui è più semplice gestire un numero negativo positivo prima di eseguire l’arrotondamento, quindi tornare indietro prima di restituire il risultato.

 function roundTo(n, digits) { var negative = false; if (digits === undefined) { digits = 0; } if( n < 0) { negative = true; n = n * -1; } var multiplicator = Math.pow(10, digits); n = parseFloat((n * multiplicator).toFixed(11)); n = (Math.round(n) / multiplicator).toFixed(2); if( negative ) { n = (n * -1).toFixed(2); } return n; } 

Fiddle: https://jsfiddle.net/3Lbhfy5s/79/

Se si utilizza un unario plus per convertire una stringa in un numero come documentato su MDN .

Ad esempio: +discount.toFixed(2)

Le funzioni Math.round () e .toFixed () intendono arrotondare al numero intero più vicino. Otterrai risultati non corretti quando hai a che fare con i decimali e usando il metodo “moltiplica e dividi” per Math.round () o parametro per .toFixed (). Ad esempio, se provi a arrotondare 1.005 usando Math.round (1.005 * 100) / 100, otterrai il risultato di 1 e 1.00 usando .toFixed (2) invece di ottenere la risposta corretta di 1.01.

È ansible utilizzare il seguente per risolvere questo problema:

 Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2'); 

Aggiungi. A Risolto (2) per ottenere i due decimali che desideri.

 Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2').toFixed(2); 

Potresti creare una funzione che gestirà l’arrotondamento per te:

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

Esempio: https://jsfiddle.net/k5tpq3pd/36/

Alternativ

È ansible aggiungere una funzione circolare a Numero utilizzando il prototipo. Non suggerirei di aggiungere .toFixed () qui come restituirebbe una stringa anziché il numero.

 Number.prototype.round = function(decimals) { return Number((Math.round(this + "e" + decimals) + "e-" + decimals)); } 

e usalo in questo modo:

 var numberToRound = 100 - (price / listprice) * 100; numberToRound.round(2); numberToRound.round(2).toFixed(2); //Converts it to string with two decimals 

Esempio https://jsfiddle.net/k5tpq3pd/35/

Fonte: http://www.jacklmoore.com/notes/rounding-in-javascript/

Per ottenere il risultato con due decimali, puoi fare così:

 var discount = Math.round((100 - (price / listprice) * 100) * 100) / 100; 

Il valore da arrotondare viene moltiplicato per 100 per mantenere le prime due cifre, quindi divideremo per 100 per ottenere il risultato effettivo.

prova a usare discount.toFixed(2);

La soluzione migliore e semplice che ho trovato è

 function round(value, decimals) { return Number(Math.round(value+'e'+decimals)+'e-'+decimals); } round(1.005, 2); // 1.01 

Riferimento: http://www.jacklmoore.com/notes/rounding-in-javascript/

Penso che il modo migliore che ho visto è moltiplicare per 10 il potere del numero di cifre, quindi fare un Math.round, infine dividendo per 10 alla potenza delle cifre. Ecco una semplice funzione che uso in typescript:

 function roundToXDigits(value: number, digits: number) { value = value * Math.pow(10, digits); value = Math.round(value); value = value / Math.pow(10, digits); return value; } 

O semplicemente javascript:

 function roundToXDigits(value, digits) { if(!digits){ digits = 2; } value = value * Math.pow(10, digits); value = Math.round(value); value = value / Math.pow(10, digits); return value; } 

Una piccola variazione sulla risposta accettata. toFixed(2) restituisce una stringa e otterrai sempre due posizioni decimali. Questi potrebbero essere zeri. Se si desidera sopprimere lo zero finale (s), è sufficiente fare questo:

 var discount = + ((price / listprice).toFixed(2)); 

Modificato: ho appena scoperto quello che sembra essere un bug in Firefox 35.0.1, il che significa che quanto sopra può dare a NaN alcuni valori.
Ho cambiato il mio codice in

 var discount = Math.round(price / listprice * 100) / 100; 

Questo dà un numero con un massimo di due cifre decimali. Se ne volevi tre, dovresti moltiplicare e dividere per 1000, e così via.
L’OP vuole sempre due cifre decimali, ma se toFixed () è rotto in Firefox, è necessario prima ripararlo.
Vedi https://bugzilla.mozilla.org/show_bug.cgi?id=1134388

Modo più veloce – più veloce di toFixed ():

DUE DECIMALI

 x = .123456 result = Math.round(x * 100) / 100 // result .12 

TRE DECIMALI

 x = .123456 result = Math.round(x * 1000) / 1000 // result .123 
  function round(num,dec) { num = Math.round(num+'e'+dec) return Number(num+'e-'+dec) } //Round to a decimal of your choosing: round(1.3453,2) 

Per gestire l’arrotondamento a un numero qualsiasi di posizioni decimali, una funzione con 2 righe di codice sarà sufficiente per la maggior parte delle esigenze. Ecco alcuni esempi di codice con cui giocare.

 var testNum = 134.9567654; var decPl = 2; var testRes = roundDec(testNum,decPl); alert (testNum + ' rounded to ' + decPl + ' decimal places is ' + testRes); function roundDec(nbr,dec_places){ var mult = Math.pow(10,dec_places); return Math.round(nbr * mult) / mult; } 
 function discoverOriginalPrice(discountedPrice, salePercentage) { var originalPrice = discountedPrice / (1 - (salePercentage * .01)); return +originalPrice.toFixed(2); } 

Ecco un esempio funzionante

 var value=200.2365455; result=Math.round(value*100)/100 //result will be 200.24