Php: How to Add Leading Zeros/Zero Padding to Float via Sprintf()

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 0010

sprintf("%04s", -10); returns 0-10

Where as:

sprintf("%04d", 10); returns 0010

sprintf("%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



Leave a reply



Submit