Edit report at http://bugs.php.net/bug.php?id=51396&edit=1
ID: 51396 Updated by: ahar...@php.net Reported by: codeslinger at compsalot dot com Summary: Math is Unreliable -Status: Open +Status: Feedback Type: Bug Package: Math related Operating System: any PHP Version: Irrelevant New Comment: It looks like the Web server you've posted the sample code to is interpreting the PHP files, so it's impossible to get the source. If you could upload the files with an extension that's not being handled by your PHP module, that would be handy. If there's any chance of a more minimal test case, that would also be rather useful. Finally, without wanting to sound overly snarky, that description was about 1200 words too long and infinitely too overwrought. Brevity is appreciated. Previous Comments: ------------------------------------------------------------------------ [2010-03-26 00:36:48] codeslinger at compsalot dot com Description: ------------ is math accuracy important? no I am not talking about round-off errors. I am talking about the fact that most of the time, php correctly says that 2+2 = 4, but that sometimes it says that 2+2 = 0. What if your paycheck was being printed by a php program and you discovered that the math is inaccurate, would you care then? I ask these questions because I previously reported this bug because it occurred in a billing system that I wrote, but nobody considered that bug important enough to pursue it. Too complex, too hard to reproduce. whatever. Well, I have now encountered this bug again, with a much simpler program. and this program demonstrates that math in php is completely and totally untrustworthy. Does anyone care that fundamental functionality is unreliable? What good is a programming language that can't do math? php passes trivial math tests just fine; it's only when you use it in complex real-world ways that it starts failing. No these aren't binary base conversion errors, I'm guessing that this is memory corruption, so far I've only observed it with thousands of calculations. But the trivial programs I wrote in an attempt to reproduce the problem never succeeded in failing. I can only get it to fail when I'm doing real-world / complex stuff Characteristics: This is not a bug in the php program; under specific conditions - described below - the php program does run correctly. The main problem occurs when a float is converted to a string by a program that makes heavy use of arrays. It's not an out of memory condition, I have successfully stress tested an array with one million items, but I am seeing it fail with only a thousand items. When it fails, the failure it totally repeatable, it always fails in exactly the same place in exactly the same way. And yet there is no discernible pattern to the failure, the trigger condition is unpredictable, it seems to depend on the actual data values. It is not a hardware issue, this has been observed on multiple machines. Also my main computer has had extensive memory diagnostic and hard disk tests run on it without finding any problems. It is not operating system specific, this failure has been observed on both Linux and Windows. It is not an FDIV bug. This Pentium chip is verified to not have that bug. Different versions of php are triggered by different sequences of events. But all of them fail in some way. I have two programs, both of which fail, but the specifics of the failure vary depending on which version of php they are being run on. One program is a billing system, it is large and complex and proprietary and the data is confidential and it uses several external libraries. The other program generates a Koch Snowflake (a type of graphics fractal). It is small and has no required dependencies and I am happy to make it's source code available. Both fail with the same or similar math errors but the behavior is not identical. The billing system *appears* to run fine on Windows PHP 5.2.5 (standard build as provided by php.net). The billing system is in daily use and no errors have been reported... so far... At one point it was decided to upgrade to PHP 5.2.9 (standard build from php.net). The billing system passed the preliminary testing with dummy data and the php upgrade was deployed to the field. Result: Can you spell NIGHTMARE?!!! I knew you could... Many instances of invalid statements being created. The math errors were repeatable. We are talking simple arithmetic about 90 percent of it is just adding, with a few multiplications. This was entered as bug #47716 Everyone was downgraded back to php 5.2.5 and the bug report was blown off. I also confirmed that the bug existed in 5.2.11 I assumed that the bug did not exist in 5.2.5 An attempt was made to test 3.x but that was impossible because the billing system requires various libraries which are not available for version 3 of php. And that is where things have sat until now. New program, Koch Snowflake generator. I'm doing some experiments with 3d graphics. This was written as a study in how to do it. I ran into exactly the same math -- string conversion bug, that the billing system ran into. But the Koch Snowflake program Fails on Ubuntu Linux with php 5.2.4!!! What triggers this bug is a very complex unpredictable sequence of events. And yet the failure is totally repeatable. Being a fractal, it has an outer loop of iterations which determine the complexity of the object. When I run 4 outer loops the program works fine, when I run 6 outer loops the program also works fine -- thus proving that it is not running out of memory. But when I run 5 outer loops the program fails and it always fails at item 7747. But wait there is more. Because when I run the Koch program on php 5.2.9 on Linux, it does not fail with the string conversion error. What this tells me is that my assumption was wrong, this bug does exist in version 5.2.5 and that my billing system is sitting on a ticking bomb for which the actual trigger is unpredictable. And that is why I am trying to get someone, anyone, to please pay attention to this bug. It is very very very serious. If this bug is not fixed I am going to have to abandon php altogether. The stock answer that people should upgrade php as the solution to all of their problems fails to take into account real-world realities. When the day comes that you can get all of the libraries to upgrade, and when you can get all of the hosting providers to upgrade and you can get most of the Linux distros to upgrade. Then, on that day, you can indeed expect that people should use a newer version of php as the solution to their problems. I would indeed love to be able to run a more current version of php, but as long as I am dependent on certain libraries and I must lease services from various hosting providers I am constrained by what is actually available in the real-world. And currently what is the most widely deployed version in the real-world is 5.2.4. Besides which, as far as I can tell, this bug exists in all versions of php since at least 5.2.4. I see no indication of it ever having been fixed in any version of php. But the difficulty is that the behavior does change, the specific trigger sequence does change depending on which version of php is being used. Someone really needs to track down the actual cause of this problem in a version that can reliably reproduce the failure and not make assumptions that it does not exist in other versions just because it was not triggered. Test script: --------------- here is a url to the Koch snowflake program http://www.compsalot.com/phpbug/kochsnowflake/ see the source code for details of how to run the program. Please keep in mind that triggering this bug is very finicky. The billing program fails in 5.2.9 and 5.2.11 and works in 5.2.5 but the snowflake program works in 5.2.9 and fails in 5.2.4... The bug is in all of these versions but triggering it is difficult. I only tested the snowflake program on Ubuntu version 8 using both the standard 5.2.4 and also a self installed 5.2.9 on Ubuntu 8. Expected result: ---------------- float 0.1 becomes string "0.1" or close to it in the case of binary conversion issues. Actual result: -------------- The BUG: The problem is that when php performs thousands of floating point operations, at some point corruption occurs and the floating point numbers get coerced into an invalid string format. For example: (float) 0.1 becomes: (string) (string:4) 0.0: note the colon, that colon is part of the corruption. A floating point number is being turned into a string containing a colon. How is that possible??? ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=51396&edit=1