Sorry, but when you are dealing with currency, you should not use PHP floats as specified in IMSoP. The reason is also in the PHP float man pages:
In addition, rational numbers that are accurately represented as floating point numbers in base 10, such as 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, regardless of the size of the mantissa. Therefore, they cannot be converted to their internal binary copies without a slight loss of accuracy. This can lead to confusing results: for example, gender ((0.1 + 0.7) * 10) usually returns 7 instead of expected 8, since the internal representation will be something like +7.9999999999999991118 ....
Therefore, never trust the action of floating-point numbers to the last digit, and do not compare floating-point numbers directly for equality. If accuracy is needed above, arbitrary precision mathematical functions and gmp functions are available.
Please note that the help page indicates that you cannot trust floating point results to the last digit, no matter how short (after the decimal point) it is .
Therefore, when you have very short floats (only 2 digits after the decimal point), the accuracy of the float (1e-6) is not really included in it, and you cannot trust them 100%.
Since it is about money, to avoid angry clients and lawsuits accusing of penis shaving ( https://en.wikipedia.org/wiki/Salami_slicing ), the real solutions are:
1) either use PHP BC math, which works with the string representation of numbers http://php.net/manual/en/book.bc.php
2) at the suggestion of IMSoP, use integers and keep the amounts in the lowest denomination (cents, euro cents or whatever you have) inside.
The first solution may be a bit more saturated resource: I didn’t use BC math very much, but storing strings and doing arbitrary precision math (which in this case can be a bit overwhelmed), by definition, has more RAM and the CPU is intensive than working with integers .
This may, however, require smaller changes in other parts of the code.
The second solution requires changes in the presentation, so that wherever the user sees the amounts, they are normalized to dollars, cents (or whatever you have).
Please note, however, that in this case you are also triggering problems with rounding risks at some point, for example:
float shown_amount; // what we show to customer: in dollars,cents int real_amount; // what we use internally: in cents shown_amount = cent_amount / 100;
you can reuse rounding problems as you are swimming again, and opportunities for rounding errors, so be careful and remember to perform calculations and rounding only on real_amount, never on show_amount