2009-05-23 7 views
8

Sto lavorando su alcuni script di output di report che devono eseguire alcuni calcoli rudimentali su alcuni valori monetari.Come eseguo in modo sicuro i calcoli relativi al denaro in PHP?

Sono a conoscenza delle limitazioni dell'aritmetica in virgola mobile a questo scopo, tuttavia i valori di input sono tutti in formato decimale, quindi se utilizzo gli operatori aritmetici su di essi, PHP li convertirà in float.

Quindi qual è il modo migliore per gestire i numeri? Dovrei usare BCMath? C'è qualcosa di simile a Decimal in .NET? O è sicuro usare gli operatori aritmetici se ritorno a int?

+0

È il motivo per cui Cobol è ancora pesantemente utilizzato in ambito finanziario. Puoi facilmente lavorare con i numeri decimali. –

risposta

10

Non lavorare in dollari ($ 1,54), lavorare in centesimi: (154c). A meno che non sia necessario svolgere attività in cui le frazioni di un centesimo sono importanti, allora lavorerai con gli interi e tutto va bene. Se sei interessato a decimi di un centesimo, allora moltiplica tutto per dieci!

+9

Generalizzazione: usa un'unità atomica per la tua valuta. – SingleNegationElimination

+0

Per convertire una valuta, le banche ci forniscono tariffe con 8 decimali. –

+0

E per la visualizzazione? Ha ancora bisogno di essere mostrato come $ 1,54. C'è qualche situazione con un numero in virgola mobile dove finirò con 1.53 o 1.55? – Shabbyrobe

8

Se si utilizza BCMath, tutti i valori verranno archiviati in stringhe e passati alle funzioni come stringhe, proprio come il risultato sarà una stringa. Pertanto, non è necessario eseguire alcuna trasmissione, ma assicurarsi che il numero assegnato alla funzione sia un valore numerico del valore. Personalmente, se la matematica richiede un'elevata precisione sul lato decimale, utilizzare BCMath.

-4

Se stai lavorando con quantità ragionevoli (a una "persona normale"), l'uso di virgola mobile non è probabile che sia un problema, specialmente se stai solo aggiungendo e sottraendo importi, piuttosto che fare, ad esempio, interesse calcoli.

Se stai cercando una soluzione rapida, non è probabile che il passaggio a numero intero ti aiuti; hai ancora a che fare con l'overflow. (Qualcuno ha modificato qui per dire che se PHP incontra un numero oltre i limiti del tipo intero, sarà interpreted as a float instead. Ma poi si ritorna al problema originale dell'utilizzo di virgola mobile!) Numeri interi arbitrari (GMP, a cui si fa riferimento pagina) può aiutare.)

Fondamentalmente, fare questo in modo sommario funziona nella maggior parte dei casi, ed è economico; farlo correttamente è un dolore serio. Il mio suggerimento è di considerare questo come un problema di business: se qualcuno si lamenta di perdere un centesimo, dare loro un dollaro, e non preoccuparsi di iniziare una soluzione reale finché non si risparmia più dollari facendo così.

+2

Che non è corretto. I punti mobili non sono in grado di rappresentare tutti i numeri di base 10. Anche con numeri piccoli e semplici addizioni/sottrazioni, puoi ottenere risultati errati. – troelskn

+0

I numeri in virgola mobile arrotondati possono rappresentare tutti i numeri compresi tra 0,01 e 1,00 (si noti che le cifre significative sono uguali). –

Problemi correlati