0

In PHP, I am writing an application which requires precision to 2 digits right of the decimal point for currency (eg: I care about 1.23 === 1.23 but no more right-side digits).

I am aware that floats are generally considered bad practice because they are imprecise with values based on the nature of converting from base 2 to base 10 right of the decimal point. However, in my research for a best practice for working with currency values, I saw some arguments that float is not good if you need precision greater than whole cent values. I clearly do not need greater precision that whole cent values.

So my questions, then, are:

  1. Is it worth going through the extra effort of storing the values as strings to be used with the bcmath library?
  2. If using the bcmath lib, should I store the values in the MySQL db as strings or decimal that MySQL supports?

Thanks!

Elly Post
  • 336
  • 3
  • 12
  • PS - Of course I have done my research on this before posting. There's lots of posts that talk about how to use `bcmath` and its value for precision, but I can't find one specifically talking about if it's _required_ for tracking only whole cent values. – Elly Post May 17 '16 at 16:19
  • 2
    Store all values using integer cents rather than dollars, so you can handle them as integers; and only use dollars for input/output – Mark Baker May 17 '16 at 16:23
  • Was about to suggest the same thing, @MarkBaker. ;-) – trincot May 17 '16 at 16:25
  • @MarkBaker thanks for the suggestion. I'm aware of that practice, but my main question is if it is necessary to go through the extra work when only 2 digit precision is necessary? – Elly Post May 17 '16 at 16:25
  • 2
    Storing as integer cents isn't really extra work, the only additional work you need is converting dollar/cent inputs to cents, and decorating outputs from cents to dollars/cents.... using bcmath would be a lot more additional work – Mark Baker May 17 '16 at 16:29
  • @MarkBaker I know it's not a great deal more work, but additional work is still more work. Ultimately, none of the suggestions so far answer the original question of if floats can handle precision to 2 decimal places. – Elly Post May 17 '16 at 16:30
  • 2
    As a general perspective, using floats is more than adequate for all but the most demanding math; you just need to be very careful with comparisons and rounding; but the general approach to dealing with money is to store (and perform any math) using the lowest integer denomination that will be used rather than use float – Mark Baker May 17 '16 at 16:33
  • @MarkBaker thanks for all the suggestions! I appreciate it. – Elly Post May 17 '16 at 16:36

2 Answers2

0

After further digging, I found the solution at Should I use BCMath for values with about 1,2 or 3 decimals?

According the the accepted answer on the given post, floats can not be guaranteed for any precision right of the decimal point.

As far as storage in the DB, it seems that storing it as a string would be the easiest option since the bcmath lib works with strings.

Community
  • 1
  • 1
Elly Post
  • 336
  • 3
  • 12
  • Why are you ignoring the option of storing `$1.23` as an integer value `123` Then you only need to convert results by `/100` and inputs as `*100`. You can then do integer maths on all of these numbers as well as search the database using `=` or `>=` or `<=` etc – RiggsFolly May 17 '16 at 16:50
  • @RiggsFolly it is a good suggestion, and the same that Mark Baker suggested above. My question was not about listing all options, but rather specifically if using anything other than a float (in this case, bcmath) is absolutely needed. – Elly Post May 17 '16 at 17:04
  • @RiggsFolly Can you calculate intrests using integer maths? – Alexander Vidaurre Arroyo Jul 30 '22 at 17:59
0

Use this to trim to two decimal places without rounding.

<?php
$a = 12.37675;
$a = floor($a * 100) / 100; // 12.37
echo $a;

or

<?php

function dollar($value) {
    return floor($value * 100) / 100;
}

$a = 12.37675;
echo dollar($a);
Brogan
  • 708
  • 5
  • 13
  • Comparing floats using `$c == $d` may generate incorrect results.... see the warning note in the [PHP Documentation](http://php.net/manual/en/language.types.float.php), and the method that it recommends for comparing floats – Mark Baker May 17 '16 at 17:43