ID: 42143 Comment by: php-lists at stanvassilev dot com Reported By: zoe at uk dot ibm dot com Status: Assigned Bug Type: Math related Operating System: win32 only PHP Version: 5CVS, 6CVS (2008-11-01) Assigned To: pajoye New Comment:
Naturally I mean bool(true) in the previous comment, not float(true)... ;) Previous Comments: ------------------------------------------------------------------------ [2009-05-24 12:45:32] php-lists at stanvassilev dot com Actually I just tested on Win32 PHP 5.2.9 VC6 TS (official php.net build) and this is a lot worse than I thought: var_dump(sqrt(-1) == 123); // float(true) var_dump(sqrt(-1) == "hi there"); // float(true) var_dump(sqrt(-1) == null); // float(true) var_dump(sqrt(-1) == false); // float(true) var_dump(sqrt(-1) == 0.1); // float(true) Instead of being equal to nothing, it's equal to almost everything... ------------------------------------------------------------------------ [2009-05-24 11:57:51] php-lists at stanvassilev dot com There are two separate bugs here. I've actually reported the other part individually but it was marked bogus (see #46868). Bug 1) PHP relies on the compiler's semantics alone for NaN comparisons, and that seems to differ from compiler to compiler, and even in the same compiler depending on the particular setup. This means on some builds NaN == NaN and on some NaN != NaN. On the current builds at On Windows in particular, VC9, however will compute NaN == NaN as false, while with VC6 it'll be false or true depending on the particular setup. Note that I'm not comparing the constants, but actual NaN (this test is carried out on a VC6 TS build of PHP 5.2.9): var_dump(NAN); // float(0) var_dump(sqrt(-1)); // float(NAN) var_dump(sqrt(-1) == sqrt(-1)); // true (should be false) This means that we should codify how exactly does NaN compare to other values and itself, and add a special case code above compiler logic in the equality operators. As a high level language, there's no need for PHP to depend on compiler's minutae, when we at the same time do such expensive operations such as checking two strings for numeric content before comparing. In the definition of NaN itself is said that NaN should not match anything or even itself, and this is the consistent implementation in all popular script languages today: http://en.wikipedia.org/wiki/NaN Given the current status quo, most deployments are under *nix, where the behavior is silent NaN (no errors, propagates on math operations having one or more NaN), and NaN doesn't match itself. So to stabilize this behavior for "niche" platforms, we just need to compiler-proof the code a bit with a special case logic (pseudo code): function equals(op1, op2) { if (is_nan(op1) || is_nan(op2)) { return false; } else { return op1 == op2; // else use current equality logic } } I've not done work on the PHP core, so I hope someone can provide the patch here. Bug 2) On Windows platforms it seems in most builds NAN is just reported as 0 (this bug). From my tests, on all current Win32 builds of 5.2.x and 5.3.x, NAN is reported as 0, including *VC9* builds. I have no idea why this is happening, but this might be a clue (implicit conversion and the value is lost): http://www.velocityreviews.com/forums/t283018-compiletime-constant- quiet-nan-double-.html The strange thing here is that math operations apparently *do* produce actual NaN (see test above on Bug 1), even if the constant NAN is 0. ------------------------------------------------------------------------ [2008-07-18 16:24:55] j...@php.net Pierre, assigning to you since Edin is MIA. ------------------------------------------------------------------------ [2007-08-03 05:24:53] paj...@php.net Little notice about VC6, using it with the very last SDK works. I'm not sure which SDK is used on our win32 build box. It may be a platform sdk bug more than a VC bug. Edin, can you try to upgrade the SDK (if we can upgrade it:)? ------------------------------------------------------------------------ [2007-08-02 22:27:25] s...@php.net Saw a bug under msvc2005 that can be related to this - get_nan() function produced FP exception. Weird thing is that it happens only if engine is started, shut down and then started again inside the same process. Maybe has something to do with some kind of floating point. Using PHP_DOUBLE_QUIET_NAN_HIGH instead seems to fix the problem. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/42143 -- Edit this bug report at http://bugs.php.net/?id=42143&edit=1