3

I have prices stored to five decimal places of precision, such as:

1.95000
2.25000
0.01150
2.10000
2.00000

When displaying prices, I'd like to show the standard $X.XX format if the rest of the digits are just zero, but if there are significant digits then I don't want to cut them out (so I can't simply use number_format()).

As an example, the above prices should display as:

1.95
2.25
0.0115
2.10
2.00

This process has to be done on hundreds of prices per page. What's an efficient way of formatting numbers in this manner?

sjagr
  • 15,983
  • 5
  • 40
  • 67
Nate
  • 26,164
  • 34
  • 130
  • 214
  • 2
    Try this if useful: echo (float)$pricestring; – Chandresh M Dec 05 '14 at 04:41
  • @Chandresh Doesn't keep two decimal places of precision when the digits to the right of the decimal point are `0`'s. Ex `echo (float)'2.00'` results in `2`. – Nate Dec 05 '14 at 04:45
  • 1
    Have you referred this one?-http://stackoverflow.com/questions/14531679/remove-useless-zero-digits-from-decimals-in-php – Chandresh M Dec 05 '14 at 04:51

2 Answers2

3

This uses a regex to match everything before the trailing 0s

$i = "$1.00";
$pattern = '/\$(\d+)\.(\d\d)(0*)/';
$replacement = '\$$1.$2';
print preg_replace($pattern,$replacement,$i);

Another way using rtrim on everything after the first 2 digits right of the decimal

$pos = strpos($i, '.') + 3;
print substr($i, 0, $pos) . rtrim(substr($i, $pos), '0');
FuzzyTree
  • 32,014
  • 3
  • 54
  • 85
  • I almost started trying to write a regex for this, then thought to myself "no.. there has to be a better way!" – Nate Dec 05 '14 at 05:06
  • @Nate I don't think there is, since you're looking for two explicit parameters: round off 0's + preserve at least 2 decimal places. You either check each separately or regex. EDIT: Hot damn – sjagr Dec 05 '14 at 05:18
  • 1
    How about `substr($i, 0, strpos($i, '.') + 2) . rtrim(substr($i, strpos($i, '.') + 2), '0')` for a one-liner? You could take the `strpos` into another variable though to lower execution time. – sjagr Dec 05 '14 at 05:24
  • @sjagr agreed, that's a faster way – FuzzyTree Dec 05 '14 at 05:36
2

This is kind of ugly but it does the job:

function formatPrice($price) {
    $out = (float)$price; // Trim off right-hand 0's
    $out = "$out"; // Typecast back to string
    if ((strlen($out) - strpos($out, '.')) <= 2) { // Test for string length after decimal point
        $out = number_format($out, 2); // Format back with 0's
    }
    return $out;
}

Testing it now... Works!

Here's a one-liner function from my other comment thanks to @FuzzyTree's answer:

function formatPrice($price) {
    return substr($price, 0, strpos($price, '.') + 3) . rtrim(substr($price, strpos($price, '.') + 3), '0');
}
sjagr
  • 15,983
  • 5
  • 40
  • 67
  • Would you want to update your answer with the comment you left on the other answer? Your one-liner works, although I had to change the `+ 2` to `+ 3`. – Nate Jan 06 '15 at 15:26
  • @Nate Sure, done! However I had already [added my comment to that answer](http://stackoverflow.com/revisions/27309026/5) – sjagr Jan 06 '15 at 15:30