-1

The sprinf behaviour below is very strange.

// The code below outputs 1639
$value = floatval('16.40') * 100;
echo sprintf('%d', $value); 

But when I use %f it outputs 1640.000000

I dumped the $value, it's definitely float(1640).

Does anyone knows what happened when I use %d? Is this a PHP bug? I've tested in PHP7.

Jonathan
  • 538
  • 1
  • 6
  • 18
  • 1
    Possible duplicate of [PHP - Floating Number Precision](https://stackoverflow.com/questions/3726721/php-floating-number-precision) – LF00 Jun 08 '17 at 09:26
  • Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – miken32 Nov 30 '18 at 00:05

1 Answers1

4

The variable $value contains a floating point number. Floating point numbers are not exact, they are approximations.1

The value of $value is not 1640 but 1639.99999999999977262632. When you use %f to print it, printf() rounds it to 6 decimal places and the rounded value is 1640.000000.

When it is printed with %d, printf() uses only the integer part of $value and it is 1639.

Use round() to get the correct integer value:

printf('%d', round($value, 0));

Or, even better, use number_format() to get the value as string:

echo(number_format($value, 0, '', ''));

Both print 1640.


1 Think of 1/3. It is approximatively 0.3333333333 but one cannot represent it exactly because it has an infinite number of 3 after the decimal dot. In mathematics, 3 * 1/3 = 1 but in real life (and in computers), 3 * 0.333333333 is never 1, no matter how many 3 we put after the decimal dot. The computer programs usually round the value to some number of decimal places and it ends up being displayed as 1 but this doesn't happen always.

When it doesn't happen, another question similar to this one pops up on StackOverflow.

axiac
  • 68,258
  • 9
  • 99
  • 134