Note:
The accuracy tends to drift if you're setting a large decimal value.
<?php
$number = 1234.560;
echo number_format($number, 2, '.', '');
echo number_format($number, 3, '.', '');
echo number_format($number, 4, '.', '');
echo number_format($number, 10, '.', '');
echo number_format($number, 20, '.', '');
echo number_format($number, 50, '.', '');
?>
echos this (for me at least).
1234.56
1234.560
1234.5600
1234.5600000000
1234.55999999999994543032
1234.55999999999994543031789362430572509765625000000000
SyCo
number_format
(PHP 4, PHP 5)
number_format — Format a number with grouped thousands
Description
This function accepts either one, two, or four parameters (not three):
If only one parameter is given, number will be formatted without decimals, but with a comma (",") between every group of thousands.
If two parameters are given, number will be formatted with decimals decimals with a dot (".") in front, and a comma (",") between every group of thousands.
If all four parameters are given, number will be formatted with decimals decimals, dec_point instead of a dot (".") before the decimals and thousands_sep instead of a comma (",") between every group of thousands.
Return Values
A formatted version of number .
Parameters
- number
-
The number being formatted.
- decimals
-
Sets the number of decimal points.
- dec_point
-
Sets the separator for the decimal point.
- thousands_sep
-
Sets the thousands separator.
Only the first character of thousands_sep is used. For example, if you use bar as thousands_sep on the number 1000, number_format() will return 1b000.
Examples
Example #1 number_format() Example
For instance, French notation usually use two decimals, comma (',') as decimal separator, and space (' ') as thousand separator. This is achieved with this line :
<?php
$number = 1234.56;
// english notation (default)
$english_format_number = number_format($number);
// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands seperator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
?>
number_format
17-Sep-2008 02:17
14-Jul-2008 05:35
Let's say we got the number $inp = 1234.56
By using
<?php
return number_format($inp, 2, ',', '.');
?>
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:
<?php
function my_number_format($number, $dec_point, $thousands_sep)
{
$tmp = explode('.', $number);
$out = number_format($tmp[0], 0, $dec_point, $thousands_sep);
if (isset($tmp[1])) $out .= $dec_point.$tmp[1];
return $out;
}
?>
15-Jun-2008 09:53
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 <0 ) {
$w = "Minus ";
//make positive
$num *= -1;
}
$snum = number_format($num,$dec,",",".");
die($snum);
$strnum = explode(".",substr($snum,0,strrpos($snum,",")));
//parse decimalnya
$koma = substr($snum,strrpos($snum,",")+1);
$isone = substr($num,0,1) ==1;
if (count($strnum)==1) {
$num = $strnum[0];
switch (strlen($num)) {
case 1:
case 2:
if (!isset($stext[$strnum[0]])){
if($num<19){
$w .=$stext[substr($num,1)]." Belas";
}else{
$w .= $stext[substr($num,0,1)]." Puluh ".
(intval(substr($num,1))==0 ? "" : $stext[substr($num,1)]);
}
}else{
$w .= $stext[$strnum[0]];
}
break;
case 3:
$w .= ($isone ? "Seratus" : terbilang(substr($num,0,1)) .
" Ratus").
" ".(intval(substr($num,1))==0 ? "" : terbilang(substr($num,1)));
break;
case 4:
$w .= ($isone ? "Seribu" : terbilang(substr($num,0,1)) .
" Ribu").
" ".(intval(substr($num,1))==0 ? "" : terbilang(substr($num,1)));
break;
default:
break;
}
}else{
$text = $say[count($strnum)-2];
$w = ($isone && strlen($strnum[0])==1 && count($strnum) <=3? "Se".strtolower($text) : terbilang($strnum[0]).' '.$text);
array_shift($strnum);
$i =count($strnum)-2;
foreach ($strnum as $k=>$v) {
if (intval($v)) {
$w.= ' '.terbilang($v).' '.($i >=0 ? $say[$i] : "");
}
$i--;
}
}
$w = trim($w);
if ($dec = intval($koma)) {
$w .= " Koma ". terbilang($koma);
}
return trim($w);
}
//example
echo terbilang(999999999999)."\n";
/**
* result : Sembilan Ratus Sembilan Puluh Sembilan Milyar Sembilan Ratus Sembilan Puluh Sembilan Juta Sembilan Ratus Sembilan Puluh Sembilan Ribu Sembilan Ratus Sembilan Puluh Sembilan
*/
echo terbilang(9999999999999999);
/**
* todo : fix this bug pleasese
* problem : number_format(9999999999999999) <--- 10.000.000.000.000.000,0000
* Result : Sepuluh Biliun
*/
10-Jun-2008 01:26
Technically, you can just use number_format() with "x" as the thousands seperator, then...
<?php
str_replace("x", "character of choice", number_format(1234.56, ".", "x"));
?>
This will probably be many times more efficient.
26-May-2008 09:45
It's pity that the function supports one-byte characters only for "thousands separator".
For English it works well but for French and Russian it makes problem.
Developers should use character   or chr(0xA0) as "thousands separator" to avoid the number of being moved to a new line in HTML-documents. But number_format() didn't understand that symbol.
To solve the problem, we wrote our own variant of number_format():
<?php
/* Replacement for number_format() */
function my_number_format($n, $decimals = 0, $dec_point = ',', $thousands_sep = ' ')
{
$b = explode('.', $n);
$rn = '';
$l = strlen($b[0]);
/* Reverse string */
for ($i = $l; $i > 3; $i -= 3)
{
$rn = $thousands_sep . substr($b[0], $i - 3, 3) . $rn;
}
/* sprintf() used to correct 0.79 to 0.790 */
/* str_replace() used to correct decimals */
/* str_repeat() used to correct decimals */
return substr($b[0], 0, $i) . $rn . ($decimals
? $dec_point.(isset($b[1])
? str_replace('0.', '', sprintf('%0.'.$decimals.'f', '0.'.$b[1]))
: str_repeat(0, $decimals))
: '');
}
/* Outputs 123 456,790 */
print my_number_format(123456.78987, 3);
?>
It can be optimized more, but this variant works well also.
13-May-2008 06:16
In response to gabrielu at gmail dot com concerning number_format(14.95 * 0.3, 2) returning 4.48 rather than 4.49:
What you're seeing is not specific to the number_format() function, but is an intractable consequence of performing floating-point arithmetic. Your computer is unable to create exact representations of certain floating-point numbers and instead approximates. The result of your calculations is stored internally not as 4.485 but as something resembling 4.484999... This is the reason for the advice to never check for equality when dealing with floating-point numbers--while PHP might echo the same thing, the internal representation could be quite different. See the code below.
<?php
$array = array();
$array['assigned'] = 4.485;
$array['calculated'] = 14.95 * 0.3; // equals 4.485 in reality
echo "Sorting ascending\n"; // notice that 'calculated' gets sorted ahead of 'assigned'
asort($array);
foreach($array as $key => $value) {
echo "$key: $value becomes " . number_format($value, 2) . "\n";
}
echo "Sorting descending\n";
arsort($array); // notice that 'assigned' gets sorted ahead of 'calculated'
foreach($array as $key => $value) {
echo "$key: $value becomes " . number_format($value, 2) . "\n";
}
?>
Output:
Sorting ascending
calculated: 4.485 becomes 4.48
assigned: 4.485 becomes 4.49
Sorting descending
assigned: 4.485 becomes 4.49
calculated: 4.485 becomes 4.48
09-May-2008 12:54
Using the number_format I'm having some unexpected results. 30% of 14.95 (14.95 * .3) = 4.485. Now 4.485 rounded to two decimal places should give me 4.49.
Example:
<?php
echo number_format(14.95 * .3, 2, '.', '') . "\n";
echo number_format(4.485, 2, '.', '') . "\n";
?>
Unexpected Results:
4.48
4.49
31-Jan-2008 05:02
I have seen some scripts here for format a filesize, but i think this can be useful:
<?php
function format_filesize($number, $decimals = 3, $force_unit = false, $dec_char = ',', $thousands_char = ' ')
{//string format_filesize(int(0,) $number, (bool(0), int(0,4)) $force_unit, int $decimals, char $dec_char, char $thousands_char)
//format a filesize $number with unit (setted by $force_unit(see below for the number))
$units = array('o', 'Ko', 'Mo', 'Go', 'To');
if($force_unit === false)
$unit = floor(log($number, 2) / 10);
else
$unit = $force_unit;
if($unit == 0)
$decimals = 0;
return number_format($number / pow(1024, $unit), $decimals, $dec_char, $thousands_char).' '.$units[$unit];
}
?>
ex:
format_filesize(2540367) => '2,423 Mo'
format_filesize(2540367, 2) => '2,42 Mo'
format_filesize(2540367, 1, 1) => '2 480,8 Ko' //0=>'o', 1=>'Ko', 2=>'Mo', 3=>'Go', 4=>'To' (see $units)
format_filesize(2540687367, 2, 1, ',', '.') => '2.481.140,01 Ko'
log($number, 2) / 10 = log($number, 1024) ;)
Fast & Easy, isn't it? :)
08-Jan-2008 04:28
I have to verify price data from several formats, eg:
- 12.345,67 (German)
- 12,345.67 (English)
- 12 345,67 (French)
- 12'345,67 (Swiss)
Here is a quick function which helps me out of all this format mess, but please not the I only check for:
- positive values
- max 2 digits on the right side (.12)
function mk_price_to_float($price){
$price = trim($price);
if(preg_match("~^([0-9]+|(?:(?:[0-9]{1,3}([.,' ]))+[0-9]{3})+)(([.,])[0-9]{1,2})?$~", $price, $r)){
if(!empty($r['2'])){
$pre = preg_replace("~[".$r['2']."]~", "", $r['1']);
}else{
$pre = $r['1'];
}
if(!empty($r['4'])){
$post = ".".preg_replace("~[".$r['4']."]~", "", $r['3']);
}else{
$post = false;
}
$form_price = $pre.$post;
return $form_price;
}
return false;
}
This code is used at http://www.produkte24.com/ and http://www.who-sells-it.com/ and works like a charm.
06-Oct-2007 05:34
A simple funtion to format american dollars.
<?
function formatMoney($money) {
if($money<1) {
$money='¢'.$money*100;
}
else {
$dollars=intval($money);
$cents=$money-$dollars;
$cents=$cents*100;
$money='$'.$dollars.' and ¢'.$cents;
}
return $money;
}
echo formatmoney('52.342');
?>
This will output: " $52 and ¢34.2 ".
12-Aug-2007 01:38
To address the problems number_format has when dealing with big numbers I've created my own Number_Format method, it acts the same way as number_format and takes the same arguments but deals with numbers as strings solving the problems above referred.
(The other methods are available at http://www.alixaxel.com/wordpress/2007/05/19/php-math-library/)
function Number_Format($number, $decimal_precision = 0, $decimals_separator = '.', $thousands_separator = ',')
{
if ($this->Is_Negative($number))
{
$negative = true;
$number = str_replace('-', '', $number);
}
$number = explode('.', str_replace(' ', '', $number));
$number[0] = str_split(strrev($number[0]), 3);
$total_segments = count($number[0]);
for ($i = 0; $i < $total_segments; $i++)
{
$number[0][$i] = strrev($number[0][$i]);
}
$number[0] = implode($thousands_separator, array_reverse($number[0]));
if ($negative === true)
{
$number[0] = '-' . $number[0];
}
if (!empty($number[1]))
{
$number[1] = $this->Round($number[1], $decimal_precision);
}
$number = implode($decimals_separator, $number);
return $number;
}
I hope this is useful for someone!
02-Aug-2007 03:39
Beware of this pitfall:
$value = number_format ($float_val, 2, ".");
This will silently return an empty string and not throw an error, at least with PHP 5.x.
This is the corrected code:
$value = number_format ($float_val, 2, ".", ",");
- or -
$value = number_format ($float_val, 2);
You must specifiy either the decimal point AND thousands separator else neither, otherwise you'll run into this issue.
I just spent over 30min debugging code with this problem!
16-Jul-2007 10:52
The following function converts a string into Float or Integer while taking the given or locale number format into account.
<?php
function strtonumber( $str, $dec_point=null, $thousands_sep=null )
{
if( is_null($dec_point) || is_null($thousands_sep) ) {
$locale = localeconv();
if( is_null($dec_point) ) {
$dec_point = $locale['decimal_point'];
}
if( is_null($thousands_sep) ) {
$thousands_sep = $locale['thousands_sep'];
}
}
$number = (float) str_replace($dec_point, '.', str_replace($thousands_sep, '', $str));
if( $number == (int) $number ) {
return (int) $number;
} else {
return $number;
}
}
?>
15-May-2007 05:14
enjoy the PHP!
<?php
function FormatPrice($price) {
$price = preg_replace("/[^0-9\.]/", "", str_replace(',','.',$price));
if (substr($price,-3,1)=='.') {
$sents = '.'.substr($price,-2);
$price = substr($price,0,strlen($price)-3);
} elseif (substr($price,-2,1)=='.') {
$sents = '.'.substr($price,-1);
$price = substr($price,0,strlen($price)-2);
} else {
$sents = '.00';
}
$price = preg_replace("/[^0-9]/", "", $price);
return number_format($price.$sents,2,'.','');
}
?>
13-Feb-2007 11:18
Aj and astrolox, for perfect precision arithmetic, you can use the bcmath functions, which perform math on string representations of numbers, instead of on floats. Obviously this is an order of magnitude slower, but at least you don't lose any precision due to the complexities of IEEE-754.
08-Feb-2007 07:38
I use the following to get around the negative zero problem:
function currency_format($amount, $precision = 2, $use_commas = true, $show_currency_symbol = false, $parentheses_for_negative_amounts = false)
{
/*
** An improvement to number_format. Mainly to get rid of the annoying behaviour of negative zero amounts.
*/
$amount = (float) $amount;
// Get rid of negative zero
$zero = round(0, $precision);
if (round($amount, $precision) == $zero) {
$amount = $zero;
}
if ($use_commas) {
if ($parentheses_for_negative_amounts && ($amount < 0)) {
$amount = '('.number_format(abs($amount), $precision).')';
}
else {
$amount = number_format($amount, $precision);
}
}
else {
if ($parentheses_for_negative_amounts && ($amount < 0)) {
$amount = '('.round(abs($amount), $precision).')';
}
else {
$amount = round($amount, $precision);
}
}
if ($show_currency_symbol) {
$amount = '$'.$amount; // Change this to use the organization's country's symbol in the future
}
return $amount;
}
06-Feb-2007 06:27
simpler function to convert a number in bytes, kilobytes....
<?php
function bytes($a) {
$unim = array("B","KB","MB","GB","TB","PB");
$c = 0;
while ($a>=1024) {
$c++;
$a = $a/1024;
}
return number_format($a,($c ? 2 : 0),",",".")." ".$unim[$c];
}
?>
you may also add others units over PeraBytes when the hard disks will reach 1024 PB :)
23-Dec-2006 01:41
I've discovered that the commas which number_format() inserts as a thousands separators causes math functions to break.
Bit of a newbie thing, but it bit me in the ass.
eg--
<?
$foo = number_format(1234, 2);
?>
$foo is now equal to 1,234.00
<?
$bar = 23;
$result = $foo+$bar;
?>
One would think $result == 1,257.00. However, because number_format added a comma to $foo, the expression will not evaluate correctly.
Instead, do things in this order:
<?
$foo=1234;
$bar=23;
$foobar=number_format($foo+$bar, 2);
?>
$foobar is now set to 1,257.00.
Another method, if you're fixing code you've already written and don't want to change a huge amount, is to remove the thousands separator, using the appropriate variable to number_format.
<?
$foo = number_format(1234, 2, '.', '');
$bar = number_format(23, 2, '.', '');
$foobar = number_format($foo+$bar, 2);
?>
$foobar will now be set to 1,257.00
24-Nov-2006 10:51
This is a simple and useful function to convert a byte number in a KB or MB:
<?
function filesize_format ($bytes) {
$bytes=(float)$bytes;
if ($bytes<1024){
$numero=number_format($bytes, 0, ',', '.')." Byte";
return $numero;
}
if ($bytes<1048576){
$numero=number_format($bytes/1024, 2, ',', '.')." KByte";
return $numero;
}
if ($bytes>=1048576){
$numero=number_format($bytes/1048576, 2, ',', '.')." MByte";
return $numero;
}
}
?>
26-Oct-2006 10:31
About the function of j-a-n at gmx dot de: it's useful, but the argument of the function is $number while the logic of the function requires it to be $in.
13-Sep-2006 10:56
You know sometimes we forget to add the basic cool stuff...
Found this over in the money_format section and felt some newbie is probably looking for it...
$val = "1000000";
echo number_format($val, 0, "", ","); // returns 1,000,000
Unfortunately, this function is not multibyte-safe. If you want to use the typographically correct separator for thousands in Swiss German and UTF-8 (‘ - Unicode 2019), you'll only get the first byte - e.g. garbage - since this function strips anything after the first byte, regardless of the charset used.
11-Aug-2006 01:04
This function formats an decimal number to a String.
But it does'n use an fixed count of decimals but calculates the needed count of decimals.
<?
function formatNumber( $number, $decimals=2, $dec_point=".", $thousands_sep=",") {
$nachkomma = abs($in - floor($in));
$strnachkomma = number_format($nachkomma , $decimals, ".", "");
for ($i = 1; $i <= $decimals; $i++) {
if (substr($strnachkomma, ($i * -1), 1) != "0") {
break;
}
}
return number_format($in, ($decimals - $i +1), $dec_point, $thousands_sep);
}
?>
Example:
formatNumber( 100.00 );
--> 100
formatNumber( 100.50 );
--> 100.5
formatNumber( 100.1234 );
--> 100.12
formatNumber( 100.12, 4 );
--> 100.12
formatNumber( 100.12345, 4 );
--> 100.1234
The modification to number_format below does what I actually want it to do, with currency, for example. I want it to show $1.40 and not $1.4 or $1.400 - except in the rare case where I have $1.435 for something, in which case I *don't* want it to round. The ugliness below serves my purpose.
function nof($number,$decimals) {
if (number_format($number,$decimals,'.',',') != $number) {
return $number;
} else {
return number_format($number,$decimals,'.',',');
}
}
01-Jun-2006 12:31
For those that need to print the word-form of a number ("twenty-three" instead of "23") I've found the following code to be useful. This code is an improvement upon that posted in 2004 by armstrong @ rice. Notably, the previous code did not properly compute large numbers (at least in PHP 4.x that I tested).
The following code adds another variable to the function, which controls the display of fractional parts, and properly calculates values one thousand and above.
Zak
~ ~ ~
function num2words($num, $c=1) {
$ZERO = 'zero';
$MINUS = 'minus';
$lowName = array(
/* zero is shown as "" since it is never used in combined forms */
/* 0 .. 19 */
"", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen");
$tys = array(
/* 0, 10, 20, 30 ... 90 */
"", "", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety");
$groupName = array(
/* We only need up to a quintillion, since a long is about 9 * 10 ^ 18 */
/* American: unit, hundred, thousand, million, billion, trillion, quadrillion, quintillion */
"", "hundred", "thousand", "million", "billion",
"trillion", "quadrillion", "quintillion");
$divisor = array(
/* How many of this group is needed to form one of the succeeding group. */
/* American: unit, hundred, thousand, million, billion, trillion, quadrillion, quintillion */
100, 10, 1000, 1000, 1000, 1000, 1000, 1000) ;
$num = str_replace(",","",$num);
$num = number_format($num,2,'.','');
$cents = substr($num,strlen($num)-2,strlen($num)-1);
$num = (int)$num;
$s = "";
if ( $num == 0 ) $s = $ZERO;
$negative = ($num < 0 );
if ( $negative ) $num = -$num;
// Work least significant digit to most, right to left.
// until high order part is all 0s.
for ( $i=0; $num>0; $i++ ) {
$remdr = (int)($num % $divisor[$i]);
$num = $num / $divisor[$i];
// check for 1100 .. 1999, 2100..2999, ... 5200..5999
// but not 1000..1099, 2000..2099, ...
// Special case written as fifty-nine hundred.
// e.g. thousands digit is 1..5 and hundreds digit is 1..9
// Only when no further higher order.
if ( $i == 1 /* doing hundreds */ && 1 <= $num && $num <= 5 ){
if ( $remdr > 0 ){
$remdr = ($num * 10);
$num = 0;
} // end if
} // end if
if ( $remdr == 0 ){
continue;
}
$t = "";
if ( $remdr < 20 ){
$t = $lowName[$remdr];
}
else if ( $remdr < 100 ){
$units = (int)$remdr % 10;
$tens = (int)$remdr / 10;
$t = $tys [$tens];
if ( $units != 0 ){
$t .= "-" . $lowName[$units];
}
}else {
$t = num2words($remdr, 0);
}
$s = $t." ".$groupName[$i]." ".$s;
$num = (int)$num;
} // end for
$s = trim($s);
if ( $negative ){
$s = $MINUS . " " . $s;
}
if ($c == 1) $s .= " and $cents/100";
return $s;
} // end num2words
26-May-2006 06:11
Again, the function for returning file size in human readable format, but with a tweek for displaying one decimal when size is less than 10 units.
<?php
function human_readable( $size )
{
$count = 0;
$format = array("B","KB","MB","GB","TB","PB","EB","ZB","YB");
while(($size/1024)>1 && $count<8)
{
$size=$size/1024;
$count++;
}
if( $size < 10 ) $decimals = 1;
else $decimals = 0;
$return = number_format($size,$decimals,'.',' ')." ".$format[$count];
return $return;
}
?>
Thanks to "php dot net at alan-smith dot no-ip dot com" and "service at dual-creators dot de".
22-May-2006 05:30
number_format is pretty fast. It's much slower than calculation though:
<?php
$start = microtime(true);
echo "<pre>";
for ($i=0;$i<100000;$i++)
{
echo number_format(microtime(true)-$start,25)."\n";
}
echo "<hr />Parsetime: ".(microtime(true)-$start);
?>
This takes 1.03 seconds all the time. Without the -$start in the number_format cmd, it takes exactly as long (I ran it about 20 times).
The simple calculation inside number_format takes relatively no time. Defining the number before entering it into number_format also gives no change:
{
$num = microtime(true)-$start;
echo number_format($num,25)."\n";
}
Which concludes it takes about .01 sec to do a thousand number_format.
If you'd do the same routine without the number_format, it'd take .75 seconds -> number_format very fast!
15-May-2006 01:58
Thanks to armstrong ~~at~~ rice ~~dot~~ edu for your number to words function. There does seem to be one glitch I've discovered, at least on my system. Hundreds work but hundreds of thousands and hundreds of millions do not. e.g. 100,000 or 100,000,000 hangs.
16-Mar-2006 05:40
// the mktime shortcut is a little trickier than it would first appear, even with a mod...
function text_number($n) {
$mod = $n % (($n > 20)?10:20);
return $n . (($mod==0)?"th":date("S",mktime(0,0,0,1,$mod,2000)));
}
// or for those who don't appreciate shorthand:
function text_number($n) {
if ($n > 20) {
$mod_factor = 10;
} else {
$mod_factor = 20;
}
$mod = $n % $mod_factor;
if ($mod == 0) {
$txt = "th";
} else {
$txt = date("S",mktime(0,0,0,1,$mod,2000));
}
return $n . $txt;
}
/*
one issue comes up in numbers that mod to zero (which mktime will associate with the 31st of December, 1999). another issue is between 23rd and 13rd, err I mean 13th. If you use 20 (or even 30) all the time, however, you'll end up with 33th (or 43th).
*/
04-Mar-2006 08:04
actually, you'd want to MOD the number to get it within a useful range first (1 .. 30).
Enjoy.
04-Mar-2006 06:15
why go to all that trouble?
date('S', mktime(0,0,0,1,$str,2000));
works just as well!
01-Mar-2006 11:34
<?php
# Function to represent a number like '2nd', '10th', '101st' etc
function text_number($n)
{
# Array holding the teen numbers. If the last 2 numbers of $n are in this array, then we'll add 'th' to the end of $n
$teen_array = array(11, 12, 13, 14, 15, 16, 17, 18, 19);
# Array holding all the single digit numbers. If the last number of $n, or if $n itself, is a key in this array, then we'll add that key's value to the end of $n
$single_array = array(1 => 'st', 2 => 'nd', 3 => 'rd', 4 => 'th', 5 => 'th', 6 => 'th', 7 => 'th', 8 => 'th', 9 => 'th', 0 => 'th');
# Store the last 2 digits of $n in order to check if it's a teen number.
$if_teen = substr($n, -2, 2);
# Store the last digit of $n in order to check if it's a teen number. If $n is a single digit, $single will simply equal $n.
$single = substr($n, -1, 1);
# If $if_teen is in array $teen_array, store $n with 'th' concantenated onto the end of it into $new_n
if ( in_array($if_teen, $teen_array) )
{
$new_n = $n . 'th';
}
# $n is not a teen, so concant the appropriate value of it's $single_array key onto the end of $n and save it into $new_n
elseif ( $single_array[$single] )
{
$new_n = $n . $single_array[$single];
}
# Return new
return $new_n;
}
?>
21-Feb-2006 02:03
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.
30-Jan-2006 11:43
Just a note to the author of the "zerofill" function, you may find it easier using the str_pad function
<?php
$num = 4;
$zerofill = 3;
echo str_pad($num, $zerofill, "0", STR_PAD_LEFT);
/* Returns the same wanted result of '004' */
?>
24-Jan-2006 07:17
A modification for kolnedra's function
<?
function humanReadable($val, $miles = 0){
if($val>=1000)
$val = humanReadable($val / 1024, ++$miles);
else {
$unidad = array('','K','M','G','T','P','E','Z','Y',
'X','W','V','U','TD','S','R',
'Q','PP','O','N','MI','L');
$val = round($val, 2).$unidad[$miles].'B';
}
return $val;
}
?>
A function to return a number with needed zeros at the beginning. Called "zerofill"
<?php
// $num = 4; $zerofill= 3; returns "004"
function zerofill ($num,$zerofill) {
while (strlen($num)<$zerofill) {
$num = "0".$num;
}
return $num;
}
?>
11-Jan-2006 02:19
Jarrat's example below has a problem. If the number is negative, the sign is dropped. It always returns positive numbers. The problem seems to be in the float cast in:
return (float) $number[0].'.'.$decimal;
I have not had a problem in PHP5 with:
return $number[0].'.'.$decimal;
22-Dec-2005 12:45
as response to mike at phpeeb dot com.
You can do aritmetic even on strings, you just need a little function to sort it out like this :
function str2no($number){
$number = str_replace(".", "", $number);
$number = str_replace(",", ".", $number);
return $number;
}
function no2str($number){
$number = number_format($number,2, ',', '.');
return $number;
}
echo no2str(str2no("1.200,50")*3);
// we use 1200.50 as input "1.200,50" is the danish string for this number
//this will output 3601.50 with right formatting = 3.601,50 as string
//nice to know when dealing with money.
10-Oct-2005 09:28
A way to let a number (in this case an ammount of money) be shown in dutch annotation:
<?
// geld(123) >>> 123
// geld(123456) >>> 1.234.567
function geld($nm) {
for ($done=strlen($nm); $done > 3;$done -= 3) {
$returnNum = ".".substr($nm,$done-3,3).$returnNum;
}
return substr($nm,0,$done).$returnNum;
}
?>
05-Oct-2005 07:04
This function formats numbers 'human readable' better (IMHO) than mircea way:
function humanReadable($val,$thousands=0){
if($val>=1000)
$val=humanReadable($val/1024,++$thousands);
else{
$unit=array('','K','M','T','P','E','Z','Y');
$val=round($val,2).$unit[$thousands].'B';
}
return $val;
}
02-Oct-2005 06:02
If you want to display a number ending with ,- (like 200,-) when there are no decimal characters and display the decimals when there are decimal characters i use:
function DisplayDouble($value)
{
list($whole, $decimals) = split ('[.,]', $value, 2);
if (intval($decimals) > 0)
return number_format($value,2,".",",");
else
return number_format($value,0,".",",") .",-";
}
01-Oct-2005 12:18
In responce to astrolox;
This is because the numbers generated by performing math are double precision (which means pretty darn accurate) and not perfect precision (which would be what you get when you do the math on paper). For example 483.00 * 0.175 equals 84.525 on paper, but the computer can't do math with perfect precision and ends up with something like 84.52499999...
If dealing with money the best practice is to perform round() on your floating point numbers and always round up to the nearest cent, or add something small like .000001 before using number_format(). Personally I prefer to round().
01-Aug-2005 11:34
Users should be aware of the following behaviour.
I'm not sure if this is a PHP bug, libc bug, or if it's even a bug at all. So I thought I'd make a comment and allow everyone else to make up their own minds.
FreeBSD 4.3 PHP 4.3.3
<?php
// the comments show the output generated by this script
echo "input 8.525 output = ". number_format( 8.525, 2, '.', "") ."\n";
echo "input 8.525 output = ". number_format(8.525, 2, '.', "") ."\n";
// input 8.525 output = 8.53
// input 8.525 output = 8.53
$a = 483.00;
$b = 0.175;
$c = $a * $b;
echo "input \$c = $c type ". gettype($c) ." output = ". number_format( $c, 2, '.', "") ."\n";
// input $c = 84.525 type double output = 84.52
$d = 17.5;
$e = ( $a / 100 ) * $d;
echo "input \$e = $e type ". gettype($e) ." output = ". number_format( $e, 2, '.', "") ."\n";
// input $e = 84.525 type double output = 84.53
echo "input 63.745 output = ". number_format(63.745, 2, '.', "") ."\n";
echo "input 64.745 output = ". number_format(64.745, 2, '.', "") ."\n";
echo "input 65.745 output = ". number_format(65.745, 2, '.', "") ."\n";
// input 63.745 output = 63.74
// input 64.745 output = 64.75
// input 65.745 output = 65.75
?>
15-Jul-2005 06:06
With one of the payment providers they required a monitary input of 12345.67 always with a 2 decimal placing even if .00
if you have a number 12345.5 with only one decimal place i could find no sutable php function to guarentee two decimal palces and add a trailing zero if required,
This fucntion should assist
function format_number($str,$decimal_places='2',$decimal_padding="0"){
/* firstly format number and shorten any extra decimal places */
/* Note this will round off the number pre-format $str if you dont want this fucntionality */
$str = number_format($str,$decimal_places,'.',''); // will return 12345.67
$number = explode('.',$str);
$number[1] = (isset($number[1]))?$number[1]:''; // to fix the PHP Notice error if str does not contain a decimal placing.
$decimal = str_pad($number[1],$decimal_places,$decimal_padding);
return (float) $number[0].'.'.$decimal;
}
/* examples */
format_number('1234'); // --> 1234.00
format_number('1234.5'); //--> 1234.50
format_number('1234.567'); //--> 1234.57
14-Jul-2005 09:53
See also the documentation for localeconv, which will provide values for decimal point and thousands separator from the C standard library.
Of course localeconv features many more locale information, like indicating to put the negative sign behind the value for some locale settings which can't be used to customize present number_format.
08-Jun-2005 08:25
You could use the following regular expression to divide
a number into parts:
$1-number without fractal part
$2-fractal part
$3-first 2 digits of the fractal part
$4-rest of the fractal part
the regex removes any leading and trailing symbols and leading zeros. It doesnt validate the number, so 12 41 is considered to be correct input!
english notation:
/^.*?[0]*([\d\s]+)(([\.][\d]{0,2})([\d]*))?.*?$/
french notation:
/^.*?[0]*([\d\s]+)(([\,][\d]{0,2})([\d]*))?.*?$/
<?php
// truncate the fractal part up to 2 digits of an "english number":
$number = '01,234.50789';
$trunc = preg_replace(
'/^.*?[0]*([\d\,]+)(([\.][\d]{0,2})([\d]*))?.*?$/',
'$1$3',
$number
);
echo $trunc;
?>
Outputs:
1,234.50
$number='e00012 41.100001e-4fasfd';
would output:
12 41.10
18-May-2005 12:04
What do you do if some of your numbers have decimal places, and some don't? You can switch between functions, but if you're building it in a loop, that's not a good solution. Instead, we have the same as below, with a slight change:
function number_format_unlimited_precision($number,$decimal = '.'){
$broken_number = explode($decimal,$number);
if($broken_number[1]==0){
return number_format($broken_number[0]);
}else{
return number_format($broken_number[0]).$decimal.$broken_number[1];
};
};
27-Apr-2005 11:54
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.
<?php
function number_format_unlimited_precision($number,$decimal = '.')
{
$broken_number = explode($decimal,$number);
return number_format($broken_number[0]).$decimal.$broken_number[1];
}
?>
02-Apr-2005 05:13
Since number_format returns a string, you must perform all mathmatical functions on the number before applying number_format:
<?
$total = 100;
$total = number_format($total, 2);
$shipping = 20.00;
$grand_total = $total + $shipping;
echo number_format($grand_total, 2);
/* The above will return 21.00 because $total is now a string, and no longer an integer or float. Since a string will have a value of 1, the addition of the two will return 21 and not 120. */
$total = 100;
$shipping = 20.00;
$grand_total = $total + $shipping;
echo number_format($grand_total, 2);
/* This works, and will return 120.00 as intended */
?>
31-Mar-2005 10:25
A bug was issued that -0,00 is invalid output from number_format(), but the bug was rejected since the number "-0.0000000000000000001E-999 is about -0". And the developer felt this was correct output.
Please beware of negative numbers close to zero, as they might produce this unusable (and in my opinion incorrect/off-description) output.
24-Mar-2005 03:14
I was looking for an easy way to take a number (or string) and force into a specific format. I came up with. I apologiz