2011-01-11 4 views
18

Sono stato sconcertante su come gestire la visualizzazione della valuta e la matematica in PHP, e per lungo tempo lo ho archiviato in MySQL usando il tipo DECIMAL e usando money_format() per formattarlo per la visualizzazione sulla pagina web. Tuttavia, oggi ho esaminato il prototipo attuale:Se avere a che fare con soldi in un float è sbagliato, allora perché money_format() lo fa?

string money_format (string $format , float $number) 

Sono un po 'confuso ora. Tutto quello che mi è stato detto è di evitare i galleggianti per soldi! Ma eccola qui, la fondamentale funzione di formattazione (diciamo che cinque volte veloce), trasmettendo l'input a un float. number_format() fa lo stesso.

Quindi le mie domande sono:

  1. A meno che non ho a che fare con i centesimi frazionali o bilioni di dollari (e ho a che fare con nessuno dei due), dovrei essere preoccupato per tutto su visualizzazione e memorizzando la valuta (ma mai in matematica) che è stata lanciata su un float? Mi avvicinerò mai all'area in cui le imprecisioni in virgola mobile cambiano le mie cifre?

  2. Se la risposta a 1 # è che dovrei davvero interessati, allora perché è money_format() costruito in questo modo?

+5

La maggior parte del INT> conversione galleggiante pericolo viene da allora fa per la matematica con i carri allegorici. 'number_format()' sta semplicemente facendo una conversione di tipo "pretty print", quindi è improbabile che i decimali a ripetizione strana creati dal processo di float-ification influenzino i risultati. –

+20

PHP non è l'epitome delle "migliori pratiche". – Gabe

+0

cosa ha detto @markb. – time4tea

risposta

19

A meno che non ho a che fare con frazionari centesimi o bilioni di dollari (e sono trattare con nessuno), dovrei essere preoccupato affatto sulla visualizzazione e la memorizzazione (ma mai facendo matematica on) valuta lanciata su un float? Mi avvicinerò mai all'area di con imprecisioni in virgola mobile cambiare le mie cifre?

Ai fini di arrotondamento/visualizzazione puri, sei al sicuro fino a quando l'errore di rappresentazione in virgola mobile in assoluto è inferiore a $ a 0,005 (in modo che arrotondamento al centesimo più vicino è corretto).

Con IEEE 754 a precisione singola, sei sicuro fino a $ 131,072.00. ($ 131,072.01 è rappresentato come 131072,015,625 mila, che arrotonda in modo errato in su.)

doppia precisione (che di PHP float usi) non manca fino $ 70,368,744,177,664.01 (che ha anche 0,015,625 mila per i centesimi). Non hai nulla di cui preoccuparti.

Se la risposta a 1 # è che dovrei davvero interessati, allora perché è money_format() costruito in questo modo?

Che tipo dovrebbe ci vorrà? PHP non ha un tipo decimale incorporato. Neanche molte altre lingue.

Questo è discusso in “Why are floating-point values so prolific?”

+0

String suona come come una buona idea come qualsiasi. Anche se sta iniziando a sembrare sempre più simile, per questioni puramente rappresentative e non matematiche, dovrei essere perfettamente a mio agio con un galleggiante. Accettato perché ha dissipato le mie paure e + 1ed per il collegamento educativo. :) – Andrew

+1

Tu dici "Non fallisce fino a ..." ma per quanto riguarda le cose come l'interesse composto? Piccoli errori possono sommarsi. – rjmunro

+0

L'OP ha chiesto informazioni sulla visualizzazione e la memorizzazione, non sulla matematica. – dan04

Problemi correlati