I've been waffling on how to deal with currency display and math in PHP, and for a long time have been storing it in MySQL using the DECIMAL
type, and using money_format()
to format it for display on the web page. However, today I looked at the actual prototype:
string money_format ( string $format , float $number )
I'm a little confused now. All I've been told is, avoid floats for money! But here it is, the fundamental formatting function (say that five times fast), casting the input to a float. number_format()
does the same.
So my questions are:
Unless I'm dealing with fractional cents or trillions of dollars (and I'm dealing with neither), should I be concerned at all about displaying and storing (but never doing math on) currency that's been cast to a float? Will I ever come close to the area of having floating point inaccuracies change my figures?
If the answer to #1 is that I should indeed be concerned, then why is money_format()
built this way?
Since the float is essentially double-counted money, it can distort the measurement of a nation's money supply by briefly inflating the amount of money in the banking system.
Because often-times, they are approximating rationals that cannot be represented finitely in base 2 (the digits repeat), and in general they are approximating real (possibly irrational) numbers which may not be representable in finitely many digits in any base.
Money and Decimal are fixed numeric datatypes while Float is an approximate numeric datatype. Results of mathematical operations on floating point numbers can seem unpredictable, especially when rounding is involved.
Float & Double are bad for financial (even for military use) world, never use them for monetary calculations. If precision is one of your requirements, use BigDecimal instead.
Unless I'm dealing with fractional cents or trillions of dollars (and I'm dealing with neither), should I be concerned at all about displaying and storing (but never doing math on) currency that's been cast to a float? Will I ever come close to the area of having floating point inaccuracies change my figures?
For pure rounding/display purposes, you're safe as long as the absolute floating-point representation error is less than $0.005 (so that rounding to the nearest cent is correct).
With IEEE 754 single-precision, you're safe up to $131,072.00. ($131,072.01 is represented as 131072.015625, which incorrectly rounds up.)
Double precision (which PHP's float
uses) doesn't fail until $70,368,744,177,664.01 (which also has .015625 for the cents). You have nothing to worry about.
If the answer to #1 is that I should indeed be concerned, then why is money_format() built this way?
What type should it take? PHP doesn't have a built-in decimal type. Nor do many other languages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With