2

This is probably one of the weirdest cases I've ever seen in debugging in PHP. This is a very simple sum: 104.85 / 34.95. The answer is 3 (use your calculator if you don't believe me ).

PHP returns a float(3), but when I use the function floor() on the sum, so floor(104.85 / 34.95), it returns a float(2). I know floats can be tricky sometimes, but I have no idea how this is possible and how I could solve this. I need the floor() functionality for my application. So if anyone has an alternative, answers are welcome.

Update: My current PHP version is 7.2.9

  • 1
    Seems that PHP 8 actually returns 2.9999999999999996 - https://3v4l.org/mn0XU – Matt Nov 12 '20 at 10:58
  • I wonder if prior to PHP 8 it's returning that value but in some sort of hidden way? – Matt Nov 12 '20 at 11:00
  • 1
    @matt It have lesser precission, running your code in php 7.4 with number_format up to 20 gives 2.99999999999999955591 – Virre Nov 12 '20 at 11:06
  • 2
    The values are stored in binary. Its for example hard to to store a value like `0.3`. Because its not a finite number (if i remember correctly) in binary, its like trying to store `1/3` (one third) in decimal. Its not only a problem in PHP but rather for many programming languages out there. – Definitely not Rafal Nov 12 '20 at 11:09
  • Thanks @Virre, good to know – Matt Nov 12 '20 at 11:11
  • @DefinitelynotRafal sounds logical, I noticed that I had the same problem in JavaScript using Math.floor(). I still need a workaround, so if you have any tips, they're all welcome. – Youness Arsalane Nov 12 '20 at 11:12
  • 1
    http://floating-point-gui.de – deceze Nov 12 '20 at 11:13
  • @YounessArsalane This seems to work floor(round(104.85/34.95,2)) , rounds to two decimals. – Virre Nov 12 '20 at 11:22
  • 1
    @Virre that might work in this specific case, but this is generally not a good solution. – Definitely not Rafal Nov 12 '20 at 11:25
  • 1
    @Virre Exactly what Definitely not Rafal said. For example if you have the sum 139.79 / 34.95, the answer is 3.99971388.... And with your workaround it returns 4 instead of 3 unfortunately – Youness Arsalane Nov 12 '20 at 11:29
  • 2
    In common Python implementations, neither 104.85 nor 34.95 is representable and using `104.85` and `34.95` in a Python script results in the values 104.849999999999994315658113919198513031005859375 and 34.9500000000000028421709430404007434844970703125. As you can see, their quotient is less than 3, so it is unsurprising that calculating the floor of the quotient yields 2. Floating-point arithmetic is designed to approximate real arithmetic. Functions such as `floor` are discontinuous; they have sudden changes at certain points, so you should expect they are sensitive to approximated inputs. – Eric Postpischil Nov 12 '20 at 19:20

0 Answers0