Why "just round()" no longer works? A look at 2025
\n\nAnyone who has ever written an online store, an accounting module, or a currency rate parser in PHP has faced the question: "How do I neatly display the number 19.9999999999999 as 20.00?" This question has gathered thousands of views on Stack Overflow, and for good reason. In 2025, when PHP proudly runs version 8.4 and higher, the old reliable tricks with round() sometimes throw surprises worthy of a horror movie.
Let's figure it out once and for all: how to display a number with two decimal places in PHP, reliably, neatly, and in line with modern standards. We won't just copy an answer from a forum — we'll understand why each method works the way it does.
\n\nProblem #1: Floating point — your treacherous friend
\n\nPHP, like most languages, uses the IEEE 754 format for floating-point numbers (float). This means that 0.1 + 0.2 might not equal 0.3, but 0.30000000000000004. And 19.95 multiplied by 100 might give 1994.9999999999998. If you simply call round(), you'll get an unexpected result.
Therefore, in 2025, rule number one is: don't trust float for finances. But if you just need to format output (e.g., a price on a storefront), then the following methods are just what the doctor ordered.
\n\nMethod #1: The classic — number_format()
\n\nThis is the most popular and safe method for 99% of tasks. The number_format() function doesn't just round — it formats a number with thousands separators and a specified number of decimal places.
<?php\n$price = 19.999999;\necho number_format($price, 2, '.', ''); // Outputs: 20.00\n\n$salary = 1234.5;\necho number_format($salary, 2, '.', ','); // Outputs: 1,234.50\n?>\n\nWhy this is great:
\n- \n
- Automatically rounds to the specified number of places (using standard mathematical rounding). \n
- Allows you to set your own decimal and thousands separators. \n
- Adds zeros if the fractional part is shorter (e.g., 5.00 instead of 5). \n
Subtle point: If you pass a string, PHP will try to convert it to a number. Be careful with locales — a comma in a string might not be interpreted as a decimal separator.
\n\nWhen to use it?
\nFor displaying prices, salaries, percentages, and any data where you need two decimal places and digit grouping.
\n\nMethod #2: Mathematical precision — round()
\n\nThe round() function returns a number (float type), not a string. This is important if you plan to do further calculations.
<?php\n$value = 45.6789;\n$rounded = round($value, 2); // 45.68 (float)\n\n// But! If you specifically need two digits and a trailing zero:\necho $rounded; // Outputs 45.68 (all good)\necho round(45.0, 2); // Outputs 45 (float), not 45.00\n?>\n\nThe pitfall: round() uses "banker's rounding" (round half to even) by default in PHP 8+. This means 2.5 rounds to 2, and 3.5 rounds to 4. This may be unacceptable for financial purposes. Use the PHP_ROUND_HALF_UP constant for classic rounding:
<?php\necho round(2.5, 0, PHP_ROUND_HALF_UP); // 3\necho round(2.5, 0); // 2 (banker's rounding)\n?>\n\nConclusion: round() + number_format()
\nThe perfect tandem: first round for calculations, then format for display.
\n\n<?php\n$raw = 19.999999;\n$precise = round($raw, 2, PHP_ROUND_HALF_UP);\necho number_format($precise, 2, '.', ''); // 20.00\n?>\n\nMethod #3: The elegance of sprintf()
\n\nThe sprintf() function is a powerful string formatting tool. Does it not round, but just truncate extra digits? No, it also rounds, but it does