Php format number thousands separator

[PHP 4, PHP 5, PHP 7, PHP 8]

number_formatFormat a number with grouped thousands

Description

number_format[
    float $num,
    int $decimals = 0,
    ?string $decimal_separator = ".",
    ?string $thousands_separator = ","
]: string

Parameters

num

The number being formatted.

decimals

Sets the number of decimal digits. If 0, the decimal_separator is omitted from the return value.

decimal_separator

Sets the separator for the decimal point.

thousands_separator

Sets the thousands separator.

Return Values

A formatted version of num.

Changelog

VersionDescription
8.0.0 Prior to this version, number_format[] accepted one, two, or four parameters [but not three].
7.2.0 number_format[] was changed to not being able to return -0, previously -0 could be returned for cases like where num would be -0.01.

Examples

Example #1 number_format[] Example

For instance, French notation usually use two decimals, comma [','] as decimal separator, and space [' '] as thousand separator. The following example demonstrates various ways to format a number:

See Also

  • money_format[] - Formats a number as a currency string
  • sprintf[] - Return a formatted string
  • printf[] - Output a formatted string
  • sscanf[] - Parses input from a string according to a format

thomas at weblizards dot de

13 years ago

It's not explicitly documented; number_format also rounds:



0.001->0.00
0.002->0.00
0.003->0.00
0.004->0.00
0.005->0.01
0.006->0.01
0.007->0.01
0.008->0.01
0.009->0.01

info at ensostudio dot ru

8 months ago

Note: use NumberFormatter to convert in human-readable format instead  user function from comments:

james at bandit dot co.nz

13 years ago

Outputs a human readable number.



Outputs:

247,704,360 -> 247.7 million
866,965,260,000 -> 867 billion

MarcM

16 years ago

For Zero fill - just use the sprintf[] function

$pr_id = 1;
$pr_id = sprintf["%03d", $pr_id];
echo $pr_id;

//outputs 001
-----------------

$pr_id = 10;
$pr_id = sprintf["%03d", $pr_id];
echo $pr_id;

//outputs 010
-----------------

You can change %03d to %04d, etc.

stm555 at hotmail dot com

17 years ago

I ran across an issue where I wanted to keep the entered precision of a real value, without arbitrarily rounding off what the user had submitted.

I figured it out with a quick explode on the number before formatting. I could then format either side of the decimal.

Lio

4 years ago

Be carreful, when you're using French notation
means : number_format[124.25, 2 , ',' , ' '] with ',' as dec_point,

Don't forget to specify thousands_sep that default is ',' to another value, otherwise function will return null.

sgj at dr dot com

19 years ago

Just an observation:
The number_format rounds the value of the variable.

$val1 = 1.233;
$val2 = 1.235;
$val3 = 1.237;

echo number_format[$val1,2,",","."]; // returns: 1,23
echo number_format[$val2,2,",","."]; // returns: 1,24
echo number_format[$val3,2,",","."]; // returns: 1,24

tomislav at firmus-grupa dot hr

9 years ago

When apply number_format on number with separator on thousands, result is wrong. This function accept number of any format

all results are: 1 225 552,55

isapoetra at gmail dot com

14 years ago

here is the code to convert number to Indonesian text, this code has limitation as is number_format function. sorry for this.
/*
* Created : Iwan Sapoetra - Jun 13, 2008
* Project : Web
* Package : cgaf
*
*/
function terbilang[ $num ,$dec=4]{
    $stext = array[
        "Nol",
        "Satu",
        "Dua",
        "Tiga",
        "Empat",
        "Lima",
        "Enam",
        "Tujuh",
        "Delapan",
        "Sembilan",
        "Sepuluh",
        "Sebelas"
    ];
    $say  = array[
        "Ribu",
        "Juta",
        "Milyar",
        "Triliun",
        "Biliun", // remember limitation of float
        "--apaan---" ///setelah biliun namanya apa?
    ];
    $w = "";

    if [$num

nospam at nospam dot com

13 years ago

Simple function to show money as only dollars if no cents, but will show 2 decimals if cents exist.

The 'cents' flag can force to never or always show 2 decimals


Cheers :]

And remember to always contribute custom functions if they might be useful to the rest of us or future versions of the php language.

liviu andrei [bls]

10 years ago

To prevent the rounding that occurs when next digit after last significant decimal is 5 [mentioned by several people below]:



have fun!

Theo Diem

19 years ago

formatting numbers may be more easy if u use number_format function.

I also wrote this :
function something[$number]
{
    $locale = localeconv[];
    return number_format[$number,
       $locale['frac_digits'],
        $locale['decimal_point'],
        $locale['thousands_sep']];
}

hope this helps =]
[]'s

info at daniel-marschall dot de

13 years ago

In my function my_number_format[] [shown below] there was a bug.

If a negative number which is smaller than 1 was entered [-0,...], then the result was wrongly positive because +0 is equal to -0 [the content of $tmp[0] which was interpretet as numeric value].

Here is the corrected version:



Thanks to Federico Cassinelli for the bug report.

[EDIT BY danbrown AT php DOT net: The original note follows.]

Let's say we got the number $inp = 1234.56

By using



you can get the German format 1.234,56. [Comma as decimal separator and point as thousand separator]

But I have a problem with that: I want to add commas as thousand separators and change the decimal-separator [this could also be done with str_replace], but I do not want to change the amount of fractional digits!

But since the 2nd argument of number_format is necessary to enter the 3rd and 4th argument, this cannot be done with number_format. You have to change the fractional digits with this function.

But I want that 1234.56 changes into 1.234,56 and 1234.567890123456 changes into 1.234,567890123456

So, I created following function, that doesn't change the amount of fractional digits:

xmontero at dsitelecom dot com

5 months ago

You can use:

    number_format[ $number, '.', ' ' ]

Rationale:

Since 2003, the Internationa Standard of Units regulated that groups of three are to be separated by spaces and not dots or commas:

We can read about the S.I. in wikipedia about the numbers:

"Spaces should be used as a thousands separator [1000000] in contrast to commas or periods [1,000,000 or 1.000.000] to reduce confusion resulting from the variation between these forms in different countries."

here //en.wikipedia.org/wiki/International_System_of_Units in the section "General Rules".

More specifically in an official document they introduce the concept of "thin space":

"for numbers with many digits the digits may be divided into groups of three by a thin space, in order to facilitate reading. Neither dots nor commas are inserted in the spaces between groups of three."

here //mcyt.educa.madrid.org/laboratorios/Documentos/Otros/documentos/si_brochure_8_en.pdf in page 41, in the section "5.3.4 Formatting numbers, and the decimal marker".

Finally, also in wikipedia, we can read about the separation of digits:

"It is also used in the International System of Units and in many countries as a thousands separator when writing numbers in groups of three digits, in order to facilitate reading."

here: //en.wikipedia.org/wiki/Thin_space

Note that "THIN SPACE" is breakable and for a non-breakable space we also have the "NARROW NO-BREAK SPACE". Nevertheless the definition is a bit different:

"Also starting from release 34 of Unicode Common Locale Data Repository [CLDR] the NNBSP is used in numbers as thousands group separator for French and Spanish locale."

We can read it here: //en.wikipedia.org/wiki/Non-breaking_space at the end of the article

So, conclusion: We can use   for the regular one or   for the non-breaking one in the number_format function to accomodate modern times and forget once and for all to use dots or commas for the thousands.

More literature:

* Archive of the PDF //web.archive.org/web/20140705194729///www.bipm.org/en/si/si_brochure/chapter5/5-3-2.html

* //www.bipm.org/en/committees/cg/cgpm/22-2003/resolution-10

zulisse at email dot it

15 years ago

simpler function to convert a number in bytes, kilobytes....



you may also add others units over PeraBytes when the hard disks will reach 1024 PB :]

Anonymous

19 days ago

Note: Changing the number format loses PHP's ability to count. So do not change number format if you wish to do anything besides showing the number.

besciualexandru at gmail dot com

6 years ago

// Here is a function that produces the same output as number_format[] but also works with numbers bigger than 2^53.

function a_number_format[$number_in_iso_format, $no_of_decimals=3, $decimals_separator='.', $thousands_separator='', $digits_grouping=3]{
    // Check input variables
    if [!is_numeric[$number_in_iso_format]]{
        error_log["Warning! Wrong parameter type supplied in my_number_format[] function. Parameter \$number_in_iso_format is not a number."];
        return false;
    }
    if [!is_numeric[$no_of_decimals]]{
        error_log["Warning! Wrong parameter type supplied in my_number_format[] function. Parameter \$no_of_decimals is not a number."];
        return false;
    }
    if [!is_numeric[$digits_grouping]]{
        error_log["Warning! Wrong parameter type supplied in my_number_format[] function. Parameter \$digits_grouping is not a number."];
        return false;
    }

            // Prepare variables
    $no_of_decimals = $no_of_decimals * 1;

            // Explode the string received after DOT sign [this is the ISO separator of decimals]
    $aux = explode[".", $number_in_iso_format];
    // Extract decimal and integer parts
    $integer_part = $aux[0];
    $decimal_part = isset[$aux[1]] ? $aux[1] : '';

        // Adjust decimal part [increase it, or minimize it]
    if [$no_of_decimals > 0]{
        // Check actual size of decimal_part
        // If its length is smaller than number of decimals, add trailing zeros, otherwise round it
        if [strlen[$decimal_part] < $no_of_decimals]{
            $decimal_part = str_pad[$decimal_part, $no_of_decimals, "0"];
        } else {
            $decimal_part = substr[$decimal_part, 0, $no_of_decimals];
        }
    } else {
        // Completely eliminate the decimals, if there $no_of_decimals is a negative number
        $decimals_separator = '';
        $decimal_part       = '';
    }

        // Format the integer part [digits grouping]
    if [$digits_grouping > 0]{
        $aux = strrev[$integer_part];
        $integer_part = '';
        for [$i=strlen[$aux]-1; $i >= 0 ; $i--]{
            if [ $i % $digits_grouping == 0 && $i != 0]{
                $integer_part .= "{$aux[$i]}{$thousands_separator}";
            } else {
                $integer_part .= $aux[$i];           
            }
        }
    }

        $processed_number = "{$integer_part}{$decimals_separator}{$decimal_part}";
    return $processed_number;
}

$original_number= 9223372036854775805;
echo a_number_format[$original_number, 4, '.',"'",3];
// Outputs: 9'223'372'036'854'775'805.1230

oelschlegel at gmail dot com

7 months ago

Setting the second argument to a value to greater than what is possible in floating point representation returns some interesting results.

info at ensostudio dot ru

8 months ago

Auto calculate decimals by default:

markagius at markagius co uk

2 years ago

If you want a number of digits after the point, but not unnecessary zeros.
Eg.
number_format[1.20000,4] = 1.2000
num_format[1.20000,4,0] = 1.2

number_format[1.20000,4] = 1.2000
num_format[1.20000,4,2] = 1.20

number_format[1.23456,4] = 1.2345
num_format[1.23456,4,2] = 1.2345

function num_format[$numVal,$afterPoint=2,$minAfterPoint=0,$thousandSep=",",$decPoint="."]{
  // Same as number_format[] but without unnecessary zeros.
  $ret = number_format[$numVal,$afterPoint,$decPoint,$thousandSep];
  if[$afterPoint!=$minAfterPoint]{
    while[[$afterPoint>$minAfterPoint] && [substr[$ret,-1] =="0"] ]{
      // $minAfterPoint!=$minAfterPoint and number ends with a '0'
      // Remove '0' from end of string and set $afterPoint=$afterPoint-1
      $ret = substr[$ret,0,-1];
      $afterPoint = $afterPoint-1;
    }
  }
  if[substr[$ret,-1]==$decPoint] {$ret = substr[$ret,0,-1];}
  return $ret;
}

divinity76 at gmail dot com

2 years ago

if you want to benchmark all costs for 5 seconds:



on my laptop rolling "Intel Core i7-8565U CPU @ 1.80GHz"  it prints:

$ php foo.php
cost 4: 1ms - 0.0010s
cost 5: 2ms - 0.0022s
cost 6: 3ms - 0.0038s
cost 7: 6ms - 0.0069s
cost 8: 14ms - 0.0147s
cost 9: 25ms - 0.0254s
cost 10: 55ms - 0.0554s
cost 11: 103ms - 0.1040s
cost 12: 184ms - 0.1848s
cost 13: 367ms - 0.3676s
cost 14: 737ms - 0.7379s
cost 15: 1881ms - 1.8810s

[with ms meaning milliseconds and s meaning seconds]

mail at igor dot vodka

3 years ago

Please be careful with stm555 at hotmail dot com's solution.
If you pass some little negative number [-1 < $number < 0] such as -0.01, the integer part would be converted to 0, so that the sign is eventually lost.
Here is a fixed version:

Svein Tjonndal [sveint at yahoo dot com]

18 years ago

If you use space as a separator, it will break on that space in HTML tables...

Furthermore, number_format doesn't like ' ' as a fourth parameter. I wrote the following function to display the numbers in an HTML table.

  function numberfix[$number]
  {
    $number = number_format[$number,0,","," "];
    return str_replace[" ", " ", $number];
  }

For use in:

mobi dot lenoe at gmail dot com

8 years ago

I'd like to comment to the old notes of "stm555" and "woodynadobhar".
They wrote about "number_format_unlimited_precision[]".
I guess many of us need that kind of function, which is the almost same function as number_format but don't round a number.

Does Anyone know any new solution in a recent PHP version?

...
If no, how about the following function? [I fixed somethings like bugs of the function in the old comment.]

Chủ Đề