0

Recently, my local environment has started echoing/saving floats with two decimal points with an additional string of numbers at the end, resulting in inaccurate numbers. This behaviour is recent; it used to behave correctly. I can't think of anything that has particularly changed.

For a truly simple, example:

echo 18.99;

This outputs:

18.989999999999998

When I json_encode an array with the value, the problem is exacerbated:

[18.989999999999998436805981327779591083526611328125]

Any idea what could be causing this issue, and how I might fix it? PHP 7.1, MacOS High Sierra 10.13.2, if it helps. Additionally, I'm using Laravel 5.5 as my framework.

Per some research I've already done, I tried changing the php_ini setting for precision to 12, 14, and 17, respectively. No change.

EDIT: I have seen other questions relating to the accuracy of floating point numbers in PHP and other languages, but as I've said, this behaviour is recent, so I don't believe this is simply an inherent flaw in the language.

CGriffin
  • 1,406
  • 15
  • 35
  • I'm running 7.1.14 on a Windows dev box and I get `18.99` as expected. – CD001 May 10 '18 at 14:33
  • So we can confirm at least that the answer isn't just 'floats suck'; that's good. – CGriffin May 10 '18 at 14:34
  • To quote: *"The reason is works on some machines and not others is because PHP doesn't directly partition memory. It calls C libraries which are built into the Operating System, which speaks to the ISA through an abstraction layer and translates into machine instructions. Assuming the Operating System follows IEEE-754 floating point standards, the processor you use will have no effect on the output, but how the Operating System's abstraction layer interprets the result and how the C libraries treat the result might. Windows will round any repeating binary to the nearest non-repeating decimal"* – CD001 May 10 '18 at 14:38
  • ^ from a comment here: https://stackoverflow.com/questions/3726721/php-floating-number-precision – CD001 May 10 '18 at 14:38
  • That sounds fair enough, but this only started recently. A month ago, `18.99` echoed correctly to `18.99`. Possibly an OS update broke it? – CGriffin May 10 '18 at 14:41
  • 2
    What have you got set for `precision` in php.ini? `echo ini_get('precision');` – iainn May 10 '18 at 14:45
  • It's currently at `12`. Per some other findings on the internet, I tried setting it to `17` - no change in behaviour. – CGriffin May 10 '18 at 14:46
  • It looks like it's being set higher than that, possibly at run-time. See https://eval.in/1002173 – iainn May 10 '18 at 14:47
  • You only actually need precision 17 to see this result - there's an explanation here: https://www.leaseweb.com/labs/2013/06/the-php-floating-point-precision-is-wrong-by-default/ - at precision 14, 15 or even 16 you get the rounded version (`18.99`) of the number. – CD001 May 10 '18 at 14:49
  • Hm. I definitely have it at 12. Just to be safe I `ini_set` it right before the echo, then echoed the `ini_get`. One line before the echo, `ini_get('precision')` is `12`. Is it possible for it to still be overridden at that point? – CGriffin May 10 '18 at 14:53
  • Ah! that's actually not completely correct. After setting the precision to 12, `echo 18.99` now correctly outputs `18.99`. However, `json_encode` continues to demonstrate the issue. – CGriffin May 10 '18 at 14:56
  • 1
    Got it! I needed to update the `precision` and `serialize_precision` inis. – CGriffin May 10 '18 at 14:58
  • Heh - I think by this point I would have either just multiplied the numbers by 100, explicitly converted them to strings before output, or fallen back on [bcmath](http://php.net/manual/en/book.bc.php) ;) – CD001 May 10 '18 at 15:00
  • Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – miken32 Nov 30 '18 at 00:08

1 Answers1

0

For any future Googlers: in my case, the issue was that the php.ini settings for precision and serialize_precision were wrong (well, wrong for my needs). How they changed I don't know; but setting them each to 14 solved the issue.

CGriffin
  • 1,406
  • 15
  • 35