792

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?

1
  • 21
    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. Commented Feb 14, 2017 at 18:18

24 Answers 24

1494
Answer recommended by PHP Collective

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.

12
  • 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 Commented Feb 26, 2014 at 22:07
  • 68
    @Á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
    Commented Mar 16, 2014 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
    Commented May 8, 2014 at 15:06
  • 1
    if you want to limit only float but not int then bcdiv($number,1,2)
    – Wasim A.
    Commented Feb 26, 2016 at 11:53
  • 4
    I think you should use bcadd(0,$yournumber,2) it will give you perfect result.
    – jewelhuq
    Commented May 31, 2018 at 19:21
380

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
?>
6
  • 17
    @khuderm round($number, 2); doesn't work. I want 520.00 not 520. Can't believe round doesn't do that by default. Commented Apr 14, 2016 at 16:00
  • 14
    It doesn't even answer the OP correctly but has over 100 votes up! Commented Feb 11, 2020 at 14:41
  • I want use number format but when 100.00 will return 100. How is it?
    – Ray Coder
    Commented Oct 27, 2020 at 11:30
  • but i need .93 if the number 123.93 @SomnathMuluk
    – Ray Coder
    Commented Oct 27, 2020 at 12:02
  • 4
    @RobSedgwick many poeple are searching for function to trim the remaining part after 3.333333333 to be 3.33 etc. Commented Dec 15, 2020 at 5:56
240

Alternatively,

$padded = sprintf('%0.2f', $unpadded); // 520 -> 520.00
5
  • 4
    So what if you want 520,00? I guess the other answer works better in that case.
    – SPRBRN
    Commented Apr 28, 2014 at 13:55
  • 3
    ^no the other answer will not give two decimal places for an int Commented Aug 19, 2014 at 12:34
  • 3
    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
    Commented Feb 22, 2017 at 5:48
  • @SPRBRN - number_format has an option to specify decimal separator character. Commented Mar 3, 2021 at 23:37
  • 2
    I tried this first but the output is converted to a string so you and I have to return it back to float again , so take care of this point Commented Jul 10, 2023 at 11:34
57

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

e.g.

echo round(5.045, 2);    // 5.05

echo round(5.055, 2);    // 5.06
9
  • 21
    I'd tried round, but it doesn't work - it won't add the extra .00. Commented Dec 19, 2010 at 15:18
  • 2
    round(520, 2) returns 520, not 520.00 as required by @Rich
    – user761100
    Commented Oct 15, 2018 at 14:59
  • 2
    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
    Commented Jul 14, 2020 at 13:24
  • 1
    @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); Commented Mar 3, 2021 at 23:54
  • 1
    Yeah, I know. That's why I said "To make numbers behave like strings, you need to use string manipulation functions".
    – fred2
    Commented Mar 5, 2021 at 3:11
33

Try:

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

The output will be:

1,234,545,454.00
3
  • 4
    That works, but the output would be a string and not a number.
    – Ethan
    Commented Feb 28, 2015 at 22:39
  • 2
    if you want to use number_format at least make it number_format($number, 2, '.', '')
    – Mihai P.
    Commented Oct 31, 2016 at 20:51
  • 1
    @Ethan - correct, this Q&A is about formatting a number as a string, with a specified number of decimal digits. Commented Mar 3, 2021 at 23:57
27

Use the PHP number_format() function.

For example,

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

The output will be:

7,234,545,423.00
22

use round(yourValue,decimalPoint) (php manual’s page) 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 ...

2
  • Hi @pankaj , I was wondering because using number_format() returns string how can I change it to 0.00 without being a string? Thank you
    – natsumiyu
    Commented Feb 15, 2023 at 0:53
  • @natsumiyu: number_format() is for returning a string, if you need a floating point number use php.net/round , round() , which is for returning a float. As written in the answer you requested feedback for in your comment, see first and last sentence, however mind comments like this one: stackoverflow.com/questions/4483540/…
    – hakre
    Commented Aug 27, 2023 at 23:29
20

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
0
16

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 BC Math 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
1
  • Thanks for the update. Works great for longitude & latitude.
    – Grant
    Commented Apr 15, 2021 at 4:16
15

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);
2
  • 3
    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
    Commented Jul 18, 2018 at 20:25
  • 3
    BC Math functions actually just stop processing at $scale fractional digits. This equals rounding towards zero.
    – Oktokolo
    Commented Aug 22, 2019 at 0:40
13
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.

1
  • 1
    This is the most universal solution if you have bcdiv (it's a stock but non-default package on centos6).
    – Shovas
    Commented Nov 13, 2018 at 15:26
11
$retailPrice = 5.989;
echo number_format(floor($retailPrice*100)/100,2, '.', ''); 

It will return 5.98 without rounding the number.

1
  • Only this can also do the job floor($retailPrice * 100) / 100; no need of number format then.
    – somsgod
    Commented Jul 26, 2019 at 9:29
10

Use the PHP number_format() function.

0
9

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

To remove this, do this:

$number = number_format($number, 2, ".", "");
2
  • is there a way that it will not return string when using number_format()?
    – natsumiyu
    Commented Feb 15, 2023 at 6:55
  • @natsumiyu: No, number_format() is for returning a string, also in it's name: format. Use round() if you're looking for a floating point number. See as well php.net/float ("Floating point numbers" in the PHP Manual).
    – hakre
    Commented Aug 27, 2023 at 23:38
8

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    
8

I make my own.

$decimals = 2;
$number = 221.12345;
$number = $number * pow(10, $decimals);
$number = intval($number);
$number = $number / pow(10, $decimals);
3
  • 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
    Commented Dec 11, 2013 at 14:43
  • 2
    Sorry, but round(), as it says, round de number, and sometimes, i do not want to round.
    – joanlgr
    Commented Dec 20, 2013 at 15:16
  • @joanlgr: 221.12345 you write in the example, but it's one of those numbers that don't exist for the computer and therefore some form of rounding - even you don't want it sometimes - already has been encoded by just writing this statement $number = 221.12345 and letting PHP parse and execute it. Adding more lines of code afterwards does not change (but repeats) it. E.g. "By definition, floating-point error cannot be eliminated, and, at best, can only be managed." from en.wikipedia.org/wiki/Floating-point_error_mitigation and the warning @ php.net/float.
    – hakre
    Commented Aug 27, 2023 at 23:49
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);

1
  • 18
    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
    Commented Nov 12, 2013 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.

0
5
$number = sprintf('%0.2f', $numbers); // 520.89898989 -> 520.89

This will give you 2 number after decimal.

1
  • 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! Commented Mar 17, 2016 at 13:25
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

2

Number without round

$double = '21.188624';
echo intval($double) . '.' . substr(end(explode('.', $double)), 0, 2);
0

Here's another solution with strtok and str_pad:

$num = 520.00
strtok(round($num, 2), '.') . '.' . str_pad(strtok('.'), 2, '0')
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
2
  • 1
    Hi @Kareem , I was wondering how can I return the decimal format not being a string? I tried your code but the return is a string. Thank you
    – natsumiyu
    Commented Feb 15, 2023 at 1:01
  • Hi @natsumiyu, you can simply declare the variable type depending on your use case. If you always need a number to be return you can edit the function to declare (int) there on the returned string. $num = (int) format_number(1234.5,2);
    – Kareem
    Commented Mar 10, 2023 at 6:27
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

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

thanks to mickmackusa for indicating the mistake

3
  • echo sprintf() is an antipattern. It is more sensibly written as printf() only. Commented May 5, 2022 at 2:26
  • I tried to use this but I still get a string value.
    – natsumiyu
    Commented Feb 15, 2023 at 0:56
  • 1
    sprintf() will never return float value, so it's really hard to understand what you are trying to achieve. Either way, both round() and sprintf() are featured in the existing answers, so I don't find this one adding anything new. Commented May 2, 2023 at 13:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.