1

I'm having issue with this particular number 10.12 when converting it to integer. Below is the code snippet of what I have tried and what is the result. Please advise if this is a bug and if I can help to report it.

<?php

echo "This is the problem, im expecting 1012". PHP_EOL;
echo intval((floatval("10.12") * 100)) . PHP_EOL; //1011

echo "Just Floatval". PHP_EOL;
echo (floatval("10.12") * 100) . PHP_EOL; //1012

echo "Convert to string (other number)". PHP_EOL;
echo intval((floatval("11.12") * 100)) . PHP_EOL; //1112

echo "Convert to string (other number)". PHP_EOL;
echo intval((floatval("10.13") * 100)) . PHP_EOL; //1013

echo "Use bcmul instead". PHP_EOL;
echo bcmul("10.12", 100) . PHP_EOL; //1012

I've also created a snippet at https://3v4l.org/cnIfL

Fikri Marhan
  • 359
  • 1
  • 9
  • 2
    I bet it's the binary problem with floats. Didn't read it all but I think this answer is talking about it. Just saw the calculation and I guess the rest is explanation of the problem. https://stackoverflow.com/a/27539234/5159168 . yup. I just read it all. This question is a duplicate of the one I link to. – Andreas Sep 18 '17 at 06:58
  • Possible duplicate of [PHP float calculation error when subtracting](https://stackoverflow.com/questions/17210787/php-float-calculation-error-when-subtracting) – Andreas Sep 18 '17 at 07:04
  • 1
    Also to learn https://stackoverflow.com/questions/588004/is-floating-point-math-broken – u_mulder Sep 18 '17 at 07:04

3 Answers3

1

My experience is that intval() returns the floor of the internal representation of the value, rather than the implied value. Eg, if the internal representation of a val corresponds to 10.11999999, intval($val*100) will return 1011 instead of the expected 1012.

Other functions, such as sprintf("d",val*100) do return the expected value.

Paul O
  • 21
  • 3
0

Use the round function (tested on PHP 8.0.10):

<?php
var_dump(intval(floatval(100 * "10.12"))); // int(1011)
var_dump(intval(round(floatval(100 * "10.12")))); // int(1012)
Ripper
  • 49
  • 2
0

This is actually the correct behavior when using typecasts from floating point values to string / int in PHP. It is due to the limited precision of floating point values.

round() rounds up or down, (int) $foo / intval($foo) always rounds down. echo rounds to the php.ini precision setting.

See this PHP Bugtracker Post for reference: https://github.com/php/php-src/issues/8028

Note that the default precision within the php.ini changed in PHP 8. PHP 8 and PHP 7 in default config behave differently.

You should prefer round over (int) / intval as it behaves more predictable.