695

What's the correct way to round a PHP string to two decimal places?

$number = "520"; // It's a string from a database

$formatted_number = round_to_2dp($number);

echo $formatted_number;

The output should be 520.00;

How should the round_to_2dp() function definition be?

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Rich Bradshaw
  • 69,588
  • 44
  • 174
  • 240
  • 17
    This really isn't "rounding". Rounding _reduces_ precision. It will not add decimal places to a number that doesn't have them. Based on many of the answers and comments, it seems like people are thinking that rounding is something it isn't. `round` is a math function, and this is just a formatting problem. – Don't Panic Feb 14 '17 at 18:18

25 Answers25

1358

You can use number_format():

return number_format((float)$number, 2, '.', '');

Example:

$foo = "105";
echo number_format((float)$foo, 2, '.', '');  // Outputs -> 105.00

This function returns a string.

Codemwnci
  • 52,744
  • 10
  • 95
  • 127
  • 8
    round() would be better for it's readability and simplicity too, but for anything critical be aware that it has been known to be buggy – StringsOnFire Feb 26 '14 at 22:07
  • 57
    @ÁlvaroG.Vicario `round` doesn't solve the OP's problem here. `round("520", 2)` returns the float `520`, and echoing that will of course not show it to 2 decimal places. For the OP's purpose - showing an integer to 2 decimal places by padding it with trailing zeroes - you need a number formatting function, not a rounding function. – Mark Amery Mar 16 '14 at 21:38
  • 4
    All the other answers are limited to decimal values with a dot notation. When you need to get `520,00` instead of `520.00`, this simply works. – SPRBRN May 08 '14 at 15:06
  • 1
    if you want to limit only float but not int then bcdiv($number,1,2) – Wasim A. Feb 26 '16 at 11:53
  • 1
    I don't think if it's because i am using `php 7.1.0` but the float-casting seems useless in my case and adding or removing will have no effect to the end result. – vdegenne Jan 18 '17 at 22:45
  • 3
    I think you should use bcadd(0,$yournumber,2) it will give you perfect result. – jewelhuq May 31 '18 at 19:21
  • If value is 1.255 and then we convert it so we will get 1.26 but what can we do if we want to get value 1.25 from 1.255. please let me know any trick for this. – Bhavin Thummar Jul 02 '19 at 13:13
  • @BhavinThummar You can use round() with mode PHP_ROUND_HALF_DOWN, as show Somnath's answer. If you want to round down, and always maintain 2dp, then you could use a mixture of this answer, and Somnath's to round first, and then use number_format to make sure it is output in the correct way. – Codemwnci Jul 08 '19 at 11:49
  • if you want to avoid round up of values and keep number to 2 decimal places this will work fine `floor($number * 100) / 100;` – somsgod Jul 26 '19 at 09:27
316

Use round() (use if you are expecting a number in float format only, else use number_format() as an answer given by Codemwnci):

echo round(520.34345, 2);   // 520.34
echo round(520.3, 2);       // 520.3
echo round(520, 2);         // 520

From the manual:

Description:

float round(float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]]);

Returns the rounded value of val to specified precision (number of digits after the decimal point). precision can also be negative or zero (default).

...

Example #1 round() examples

<?php
    echo round(3.4);         // 3
    echo round(3.5);         // 4
    echo round(3.6);         // 4
    echo round(3.6, 0);      // 4
    echo round(1.95583, 2);  // 1.96
    echo round(1241757, -3); // 1242000
    echo round(5.045, 2);    // 5.05
    echo round(5.055, 2);    // 5.06
?>

Example #2 mode examples

<?php
    echo round(9.5, 0, PHP_ROUND_HALF_UP);   // 10
    echo round(9.5, 0, PHP_ROUND_HALF_DOWN); // 9
    echo round(9.5, 0, PHP_ROUND_HALF_EVEN); // 10
    echo round(9.5, 0, PHP_ROUND_HALF_ODD);  // 9

    echo round(8.5, 0, PHP_ROUND_HALF_UP);   // 9
    echo round(8.5, 0, PHP_ROUND_HALF_DOWN); // 8
    echo round(8.5, 0, PHP_ROUND_HALF_EVEN); // 8
    echo round(8.5, 0, PHP_ROUND_HALF_ODD);  // 9
?>
Jacopo Pace
  • 380
  • 5
  • 11
Somnath Muluk
  • 51,453
  • 32
  • 215
  • 222
224

Alternatively,

$padded = sprintf('%0.2f', $unpadded); // 520 -> 520.00
Marc B
  • 348,685
  • 41
  • 398
  • 480
  • 3
    So what if you want `520,00`? I guess the other answer works better in that case. – SPRBRN Apr 28 '14 at 13:55
  • 2
    ^no the other answer will not give two decimal places for an int – pythonian29033 Aug 19 '14 at 12:34
  • 2
    other reasons you may want this is you dont want rounding... or in my cause SQL floats returned are not treated the same as normal floats which is a PHP math bug – Amb3rL4nn Feb 22 '17 at 05:48
  • @SPRBRN - [number_format](https://www.php.net/manual/en/function.number-format.php) has an option to specify decimal separator character. – ToolmakerSteve Mar 03 '21 at 23:37
48

http://php.net/manual/en/function.round.php

e.g.

echo round(5.045, 2);    // 5.05

echo round(5.055, 2);    // 5.06
aksu
  • 5,163
  • 5
  • 22
  • 38
SystemX17
  • 3,409
  • 4
  • 24
  • 35
  • Round will do the exact functionality that Rich is wanting, but number_format() would be more interesting to look into for all kinds of numerical formatting. – Shamim Hafiz - MSFT Dec 19 '10 at 15:15
  • This method will perform rounding as well over just forcing the digits ".00" on the end. – SystemX17 Dec 19 '10 at 15:15
  • 16
    I'd tried round, but it doesn't work - it won't add the extra .00. – Rich Bradshaw Dec 19 '10 at 15:18
  • Try using one of the examples I have there, it on it's own in a PHP script. You should get the commented result. If not then you have a problem with your PHP setup somewhere. – SystemX17 Dec 20 '10 at 02:13
  • 2
    round(520, 2) returns 520, not 520.00 as required by @Rich – user761100 Oct 15 '18 at 14:59
  • 1
    Update for PHP 7.4+ since this answer is very old. Since round returns a float it can only be guaranteed to return a number with at most one decimal place (ie, it returns something that is not an integer, with the minimum number of decimal places possible to represent the number). So `round(1,2)` (or any level or precision) returns '*1.0*', because '1.00' would not be a valid float. To make numbers behave like strings, you need to use string manipulation functions. (Previous versions of PHP may have acted differently/less logically) – fred2 Jul 14 '20 at 13:24
  • @fred2 - To convert float to a string with desired format, use `sprintf` or `number_format`. Internally, a float isn't `3.0`; its simply a binary value that is at (or sometimes very close to) 3. To convert to a string that has two decimal digits: `$str = sprintf("%0.2f", $value);` – ToolmakerSteve Mar 03 '21 at 23:54
  • Yeah, I know. That's why I said "To make numbers behave like strings, you need to use string manipulation functions". – fred2 Mar 05 '21 at 03:11
31

Try:

$number = 1234545454; 
echo  $english_format_number = number_format($number, 2); 

The output will be:

1,234,545,454.00
Leigh
  • 28,605
  • 10
  • 52
  • 98
Biju
  • 319
  • 3
  • 2
19

Use the PHP number_format() function.

For example,

$num = 7234545423;
echo number_format($num, 2);

The output will be:

7,234,545,423.00
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Sani Kamal
  • 1,061
  • 14
  • 25
18

You can use the PHP printf or sprintf functions:

Example with sprintf:

$num = 2.12;
echo sprintf("%.3f", $num);

You can run the same without echo as well. Example: sprintf("%.3f", $num);

Output:

2.120

Alternatively, with printf:

echo printf("%.2f", $num);

Output:

2.124
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Aditya P Bhatt
  • 20,351
  • 17
  • 80
  • 103
13

Another more exotic way to solve this issue is to use bcadd() with a dummy value for the $right_operand of 0.

$formatted_number = bcadd($number, 0, 2);
powtac
  • 39,317
  • 26
  • 112
  • 166
  • 2
    Note that `bc*` functions do not round up, they always round down. For example, `bcadd("1.0999","0.0",1)` yields "1.0", not "1.1". – ColinM Jul 18 '18 at 20:25
  • 2
    BC Math functions actually just stop processing at `$scale` fractional digits. This equals rounding towards zero. – Oktokolo Aug 22 '19 at 00:40
11
bcdiv($number, 1, 2) // 2 varies for digits after the decimal point

This will display exactly two digits after the decimal point.

Advantage:

If you want to display two digits after a float value only and not for int, then use this.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Wasim A.
  • 9,201
  • 21
  • 89
  • 117
  • This is the most universal solution if you have bcdiv (it's a stock but non-default package on centos6). – Shovas Nov 13 '18 at 15:26
10
$retailPrice = 5.989;
echo number_format(floor($retailPrice*100)/100,2, '.', ''); 

It will return 5.98 without rounding the number.

Pang
  • 9,073
  • 146
  • 84
  • 117
mrphpguru
  • 123
  • 1
  • 6
  • Only this can also do the job `floor($retailPrice * 100) / 100;` no need of number format then. – somsgod Jul 26 '19 at 09:29
9

Here I get two decimals after the . (dot) using a function...

function truncate_number($number, $precision = 2) {

    // Zero causes issues, and no need to truncate
    if (0 == (int)$number) {
        return $number;
    }

    // Are we negative?
    $negative = $number / abs($number);

    // Cast the number to a positive to solve rounding
    $number = abs($number);

    // Calculate precision number for dividing / multiplying
    $precision = pow(10, $precision);

    // Run the math, re-applying the negative value to ensure
    // returns correctly negative / positive
    return floor( $number * $precision ) / $precision * $negative;
}

Results from the above function:

echo truncate_number(2.56789, 1); // 2.5
echo truncate_number(2.56789);    // 2.56
echo truncate_number(2.56789, 3); // 2.567

echo truncate_number(-2.56789, 1); // -2.5
echo truncate_number(-2.56789);    // -2.56
echo truncate_number(-2.56789, 3); // -2.567

New Correct Answer

Use the PHP native function bcdiv

echo bcdiv(2.56789, 1, 1);  // 2.5
echo bcdiv(2.56789, 1, 2);  // 2.56
echo bcdiv(2.56789, 1, 3);  // 2.567
echo bcdiv(-2.56789, 1, 1); // -2.5
echo bcdiv(-2.56789, 1, 2); // -2.56
echo bcdiv(-2.56789, 1, 3); // -2.567
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Mr. HK
  • 2,121
  • 1
  • 16
  • 27
9

Use the PHP number_format() function.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Shamim Hafiz - MSFT
  • 20,466
  • 38
  • 110
  • 169
9

For conditional rounding off ie. show decimal where it's really needed otherwise whole number

123.56 => 12.56

123.00 => 123

$somenumber = 123.56;

$somenumber = round($somenumber,2);

if($somenumber == intval($somenumber))
{
    $somenumber = intval($somenumber);
}

echo $somenumber; // 123.56


$somenumber = 123.00;

$somenumber = round($somenumber,2);

if($somenumber == intval($somenumber))
{
    $somenumber = intval($somenumber);
}

echo $somenumber; // 123    
Vinay
  • 7,076
  • 4
  • 23
  • 45
8

I make my own.

$decimals = 2;
$number = 221.12345;
$number = $number * pow(10, $decimals);
$number = intval($number);
$number = $number / pow(10, $decimals);
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
joanlgr
  • 99
  • 1
  • 4
  • 1
    Its nice to see some of the maths needed to do this. Although using a built in function is preferred for me. Theres no point re-inventing the wheel. – Lightbulb1 Dec 11 '13 at 14:43
  • 2
    Sorry, but round(), as it says, round de number, and sometimes, i do not want to round. – joanlgr Dec 20 '13 at 15:16
7

round_to_2dp is a user-defined function, and nothing can be done unless you posted the declaration of that function.

However, my guess is doing this: number_format($number, 2);

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
ajreal
  • 45,869
  • 10
  • 83
  • 118
  • 17
    From your first paragraph, I think you've misunderstood the question. `round_to_2dp($number);` was meant as pseudocode; the OP was asking for somebody to tell him what to replace that expression with. – Mark Amery Nov 12 '13 at 16:23
6
$twoDecNum = sprintf('%0.2f', round($number, 2));

The rounding correctly rounds the number and the sprintf forces it to 2 decimal places if it happens to to be only 1 decimal place after rounding.

Tunaki
  • 125,519
  • 44
  • 317
  • 399
JohnS
  • 61
  • 1
  • 1
6

use roud(yourValue,decimalPoint) or number_format(yourValue,decimalPoint);

number_format() return value as string like this type 1,234.67. so in this case you can not use it for addition or any calculation. if you try then you have to deal with Number Format Error...

In this case round(121222.299000000,2) will be better option. The result would be 121222.29 ...

pankaj
  • 555
  • 7
  • 20
5

If you want to use two decimal digits in your entire project, you can define:

bcscale(2);

Then the following function will produce your desired result:

$myvalue = 10.165445;
echo bcadd(0, $myvalue);
// result=10.11

But if you don't use the bcscale function, you need to write the code as follows to get your desired result.

$myvalue = 10.165445;
echo bcadd(0, $myvalue, 2);
// result=10.11

To know more

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
jewelhuq
  • 1,154
  • 13
  • 19
4
$number = sprintf('%0.2f', $numbers); // 520.89898989 -> 520.89

This will give you 2 number after decimal.

Kampai
  • 22,335
  • 20
  • 91
  • 93
S'copion Sam
  • 59
  • 1
  • 2
  • 4
    No it won't. I don't know when this post was written but if you try it with your own example, at least on my machine :-) , it will output 520.90. Meaning, Rounding WILL occur. Be careful! – Boaz Rymland Mar 17 '16 at 13:25
3

Adding to other answers, since number_format() will, by default, add thousands separator.

To remove this, do this:

$number = number_format($number, 2, ".", "");
Glorious Kale
  • 1,195
  • 13
  • 25
2

Number without round

$double = '21.188624';
echo intval($double) . '.' . substr(end(explode('.', $double)), 0, 2);
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Abhishek Sharma
  • 300
  • 2
  • 7
1

Here's another solution with strtok and str_pad:

$num = 520.00
strtok(round($num, 2), '.') . '.' . str_pad(strtok('.'), 2, '0')
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Bryan
  • 3,241
  • 1
  • 18
  • 23
0
  • Choose the number of decimals
  • Format commas(,)
  • An option to trim trailing zeros

Once and for all!

function format_number($number,$dec=0,$trim=false){
  if($trim){
    $parts = explode(".",(round($number,$dec) * 1));
    $dec = isset($parts[1]) ? strlen($parts[1]) : 0;
  }
  $formatted = number_format($number,$dec); 
  return $formatted;
}

Examples

echo format_number(1234.5,2,true); //returns 1,234.5
echo format_number(1234.5,2);      //returns 1,234.50
echo format_number(1234.5);        //returns 1,235
Kareem
  • 4,615
  • 40
  • 35
0

In case you use math equation like I did you can set it like this:

{math equation="x + y" x=4.4444 y=5.0000 format="%.2f"}
paulalexandru
  • 8,941
  • 4
  • 61
  • 92
0

That's the same question I came across today and want to round a number and return float value up to a given decimal place and it must not be string (as returned from number_format) the answer is

echo sprintf('%.' . $decimalPlaces . 'f', round($number, $decimalPlaces));

Rehan Anis
  • 718
  • 1
  • 5
  • 7