L’arrotondamento in virgola mobile è un’attività che tutti gli sviluppatori devono eseguire prima o poi. Esistono in realtà diversi tipi di algoritmi di arrotondamento, tra cui:
- arrotondare
- arrotondare
- round-verso-più vicino
- arrotondamento aritmetico
- mezzo giro
- arrotondato a metà
- round-half-even
- tondo-metà-dispari
- round verso lo zero
- tondo-da-zero
- soffitto rotondo
- piano tondo
- troncamento (taglio)
- tondo-alternato
- round-random (arrotondamento stocastico)
per citarne solo alcuni. Di questi, probabilmente hai più familiarità con mezzo giro, che è descritto dalla seguente frase mnemonica:
5 o più? Aumenta il punteggio. 4 o meno? Lascia riposare.
Tutti i linguaggi di programmazione più diffusi, incluso JavaScript, forniscono una funzione di arrotondamento integrata. Stranamente, JavaScript tondo() la funzione è molto semplice, arrotondando solo all’intero più vicino. Ciò non significa che non puoi arrotondare al decimale più vicino; solo che dovrai lavorare un po ‘per farlo. Questo articolo descriverà alcuni approcci diversi per eseguire l’arrotondamento per eccesso e mezzo a un determinato numero di cifre decimali.
L’oggetto matematico
Math è un oggetto integrato che include proprietà statiche e metodi per costanti e funzioni matematiche. Le costanti includono PI (3.14159), LN2 (Logaritmo naturale di 2), e SQRT1_2 (Radice quadrata di ½), mentre le funzioni includono addominali() (valore assoluto), cos() (coseno) e, naturalmente, tondo(). Poiché tutte le proprietà e i metodi dei membri di Math sono statici, non è necessario creare un’istanza di un oggetto Math per utilizzarli. Invece, abbiamo solo bisogno di anteporre la proprietà o il metodo con l’oggetto Math, cioè Math.round().
Inoltre Math.round(), ci sono alcune altre funzioni che possono aiutare con le operazioni di arrotondamento. Questi includono:
- Math.floor(): arrotonda per difetto all’intero più vicino
- Math.ceil(): arrotonda all’intero più vicino
- Math.trunc(): restituisce la parte intera di un numero, rimuovendo eventuali cifre frazionarie.
Noterai che tutte queste funzioni hanno una cosa in comune: sono tutte arrotondate all’intero più vicino. Continua a leggere per sapere come arrotondare a una determinata cifra decimale.
Espansione sulla funzione Math.round()
Stai cercando di visualizzare 33.76538 nel formato valuta standard? Che ne dite di PI a dieci decimali? La formattazione dei numeri con un numero specifico di posizioni decimali può ancora essere eseguita utilizzando il Math.round() funzione, ma richiederà un po’ di moltiplicazione e divisione. Ecco alcuni esempi da dimostrare:
var original = 33.76538; // 1) round to one decimal var result = Math.round(original * 10) / 10; //returns 33.8 // 2) round to two decimals result = Math.round(original * 100) / 100; //returns 33.77 // 3) round to three decimals result = Math.round(original * 1000) / 1000; //returns 33.765
Come visto sopra, la formula per arrotondare qualsiasi numero a x punti decimali è:
- Moltiplica il numero originale per 10^x (10 alla potenza di x).
- Applicare Math.round() al risultato.
- Dividi il risultato per lo stesso numero 10^x per cui hai moltiplicato originariamente.
Numeri in virgola mobile ed errori di arrotondamento
Sebbene la formula sopra funzioni la maggior parte delle volte, ci sono alcuni numeri che comporteranno un arrotondamento verso il basso, piuttosto che verso l’alto.
Math.round(0.145 * 100)/100; //returns 0.14!?!
Questo risultato è sbagliato, in quanto avrebbe dovuto essere arrotondato a 0,15. Il problema è che JavaScript ha una precisione limitata quando rappresenta i numeri in virgola mobile. Alcuni numeri richiedono molti decimali di precisione:
0.145 * 100 = 14.499999999999998
Mentre altri no:
33.76538 * 100 = 3376.538
Per essere onesti, questo non è un problema JavaScript, ma riguarda tutti i linguaggi di programmazione. A causa dei numeri in virgola mobile con un numero limitato di cifre, non sono in grado di rappresentare accuratamente tutti i numeri reali. Pertanto, quando ci sono più cifre di quelle consentite dal formato, quelle rimanenti vengono omesse e il numero viene arrotondato per difetto.
Notazione esponenziale
Molte soluzioni sono state proposte negli anni, da semplici a molto complesse. Il più semplice che conosco è rappresentare i numeri usando notazione esponenziale:
Number(Math.round(0.145+'e2')+'e-2') = 0.15 // Yay!
Questa soluzione è stata incorporata in una funzione che puoi utilizzare nelle tue applicazioni:
function roundHalfUp(value, decimals) { return Number(Math.round(value+'e'+decimals)+'e-'+decimals); } roundHalfUp(1.005, 2); // 1.01
Numero.EPSILON
Un’altra soluzione è eseguire intorno al più vicino (usando “arrotondare a metà da zero”), in cui correzione epsilon viene applicato prima di chiamare la funzione di arrotondamento. Funziona aggiungendo il valore float più piccolo possibile al prodotto prima dell’arrotondamento. Dopo aver aggiunto Numero.EPSILON, il valore di 0,145 * 100, che è 14.499999999999998, verrà corretto in 14.5000000000000002. Tale importo verrà arrotondato per eccesso a 15, con il risultato finale di 0,15:
function roundToNearest(num, decimals) { decimals = decimals || 0; var p = Math.pow(10, decimals); var n = (num * p) * (1 + Number.EPSILON); return Math.round(n) / p; } roundToNearest(1.005, 2); // 1.01
Conclusione
L’arrotondamento dei numeri in virgola mobile non è esente da problemi, sia in JavaScript che in qualsiasi altro linguaggio. Ma, come dice il proverbio, “dove c’è una volontà, c’è un modo!” Il Math.round() funzione ti porterà almeno a metà. Una volta lì, potresti anche continuare sul traguardo. Questo è l’arrotondamento dopotutto!