PHP: How to add leading zeros/zero padding to float via sprintf()?
Short answer: sprintf('%05.2f', 1);
will give the desired result 01.00
Note how %02
was replaced by %05
.
Explanation
This forum post pointed me in the right direction: The first number does neither denote the number of leading zeros nor the number of total charaters to the left of the decimal seperator but the total number of characters in the resulting string!
Example
sprintf('%02.2f', 1);
yields at least the decimal seperator ".
" plus at least 2 characters for the precision. Since that is already 3 characters in total, the %02
in the beginning has no effect. To get the desired "2 leading zeros" one needs to add the 3 characters for precision and decimal seperator, making it sprintf('%05.2f', 1);
Some code
$num = 42.0815;
function printFloatWithLeadingZeros($num, $precision = 2, $leadingZeros = 0){
$decimalSeperator = ".";
$adjustedLeadingZeros = $leadingZeros + mb_strlen($decimalSeperator) + $precision;
$pattern = "%0{$adjustedLeadingZeros}{$decimalSeperator}{$precision}f";
return sprintf($pattern,$num);
}
for($i = 0; $i <= 6; $i++){
echo "$i max. leading zeros on $num = ".printFloatWithLeadingZeros($num,2,$i)."\n";
}
Output
0 max. leading zeros on 42.0815 = 42.08
1 max. leading zeros on 42.0815 = 42.08
2 max. leading zeros on 42.0815 = 42.08
3 max. leading zeros on 42.0815 = 042.08
4 max. leading zeros on 42.0815 = 0042.08
5 max. leading zeros on 42.0815 = 00042.08
6 max. leading zeros on 42.0815 = 000042.08
Formatting a number with leading zeros in PHP
Use sprintf
:
sprintf('%08d', 1234567);
Alternatively you can also use str_pad
:
str_pad($value, 8, '0', STR_PAD_LEFT);
Sprintf floating a 18,16 float with right padding zeros
This test code:
$data = array(
12.12234,
1.01
);
foreach($data as $fMyFloat){
echo sprintf('%18.016f', $fMyFloat) . PHP_EOL;
}
... prints this in my 64-bit computer:
12.1223399999999994
1.0100000000000000
You are facing the well-known problem of floating point precision. Converting integers from base 10 to base 2 is pretty straightforward (and exact) but base 10 floating point numbers cannot always be represented exactly in base 2. This issue isn't specific to PHP but there's a warning in the PHP manual:
Floating point numbers have limited precision. Although it depends on
the system, PHP typically uses the IEEE 754 double precision format,
which will give a maximum relative error due to rounding in the order
of 1.11e-16. Non elementary arithmetic operations may give larger
errors, and, of course, error propagation must be considered when
several operations are compounded.Additionally, rational numbers that are exactly representable as
floating point numbers in base 10, like 0.1 or 0.7, do not have an
exact representation as floating point numbers in base 2, which is
used internally, no matter the size of the mantissa. Hence, they
cannot be converted into their internal binary counterparts without a
small loss of precision
Your only chance to achieve such precision is to manipulate numbers as strings. PHP bundles two arbitrary precision libraries that can help you when you need to do match with strings: GNU Multiple Precision and BC Math. Here's a little hack with bcmath:
$data = array(
'12.12234',
'1.01'
);
bcscale(16);
foreach($data as $fMyFloat){
echo bcdiv($fMyFloat, 1) . PHP_EOL;
}
It this case, though, you can probably use simple string functions:
$data = array(
'12.12234',
'1.01'
);
foreach($data as $fMyFloat){
list($a, $b) = explode('.', $fMyFloat);
echo $a . '.' . str_pad($b, 16, 0) . PHP_EOL;
}
How use sprintf to output a floating point number lesser then 1 without a leading decimal place?
It's not possible to trim the zero before a decimal as any option with sprintf()
and float
.
sprintf() fF
The double argument is rounded and converted to decimal notation in
the style [-]ddd.ddd, where the number of digits after the
decimal-point character is equal to the precision specification. If
the precision is missing, it is taken as 6; if the precision is
explicitly zero, no decimal-point character appears. If a decimal
point appears, at least one digit appears before it.
↳ http://www-sbras.nsc.ru/cgi-bin/www/unix_help/man-cgi?sprintf
As an alternative to ltrim()
you could use substr
perhaps:
substr(sprintf('%.6f', 0.12345678), 1);
format a floating number using PHP
Try this
sprintf('%05.2f', 1.7);
PHP prepend leading zero before single digit number, on-the-fly
You can use sprintf: http://php.net/manual/en/function.sprintf.php
<?php
$num = 4;
$num_padded = sprintf("%02d", $num);
echo $num_padded; // returns 04
?>
It will only add the zero if it's less than the required number of characters.
Edit: As pointed out by @FelipeAls:
When working with numbers, you should use %d
(rather than %s
), especially when there is the potential for negative numbers. If you're only using positive numbers, either option works fine.
For example:
sprintf("%04s", 10);
returns 0010sprintf("%04s", -10);
returns 0-10
Where as:
sprintf("%04d", 10);
returns 0010sprintf("%04d", -10);
returns -010
PHP integer part padding
You can also use printf()
functions to pad the integer :
Something like (codepad):
<?php
function pad($n) {
$n = explode('.', (string)$n);
if (2 === count($n)) {
return sprintf("%02d.%d\n", $n[0], $n[1]);
}
return sprintf("%02d\n", $n[0]);
}
foreach (array(2, 22, 222, 2., 2.11) as $num) {
echo pad($num);
}
// returns 02, 22, 222, 02, 02.11
How to format numbers with 00 prefixes in php?
Use str_pad().
$invID = str_pad($invID, 4, '0', STR_PAD_LEFT);
How do I format a number to have a fixed precision AND a fixed number of integral digits?
This should work for you:
echo sprintf("%06.3f", 2.31);
Output:
02.310
Related Topics
Is It Acceptable to Use a Mix of Object Oriented Style with Procedural Style in Coding PHP
Set Multiple='False' in a Form in a Many to Many Relation Symfony2
Html5 Input Type File's Multiple Attribute Not Working in Ie
Shell_Exec() Timeout Management & Exec()
PHP Replace All Spaces with Hyphens
How to Solve This "Warning: MySQLi_Connect(): (Hy000/1049): Unknown Database" Problem
Pass a Variable to an Assetic Asset Url in Symfony2
How to Use Bind_Param for Order By
Soapclient: How to Pass Multiple Elements with Same Name
How to Validate Non-English (Utf-8) Encoded Email Address in JavaScript and PHP
Replace the Last Comma in a String Using Regular Expression
Call to Undefined Function Oci_Connect, PHP_Oci8_12C.Dll, Windows 8.1, PHP5.6.6
Merge a Table and a Change Log into a View in Postgresql