Hi (again) Ilia, all, After thinking about the zend_smart_strcmp() issue more, I believe a numeric comparison can be used except when *both* values overflow *and* have the same sign (either INF or -INF). I also think it's OK to say an underflow (that becomes an even 0.0) of both values can simply be considered a floating-point precision loss. I've updated the function to reflect this. Sound like an acceptable/good solution?
The old is_numeric_* function caused a string comparison if *either* value overflowed, so an expression like ('123' < str_repeat('1', 500)) was FALSE; it's now TRUE, which seems correct. BTW, I noticed another bug that considered '-2000000000' to be *greater than* '2000000000' because of overflow subtracting longs. I changed it to be the same as in compare_function() where this bug was fixed exactly 6 years ago. :-) Finally, speaking of compare_function(), _smart_strcmp() now uses a (double) cast too instead of _strtod() when dealing with a long/double combo. Patches are updated: http://realplain.com/php/is_numeric.diff http://realplain.com/php/is_numeric_5_2.diff Hopefully everything is now in good shape for inclusion. :-? Matt ----- Original Message ----- From: "Matt Wilmas" Sent: Monday, December 18, 2006 > Hi Ilia, all, > > I was just looking at zendi_smart_strcmp() and realized something I hadn't > considered (more on that in a sec.). First, and unrelated to the new > is_numeric_*, because _smart_strcmp() uses zend_strtod() if one operand is a > double and the other isn't, it results in ('0.0' == '0x123') being TRUE! > Seems like a bug. I think a (double) cast can be used there instead of > zend_strtod(), since that's what's done in compare_function()? Would be > faster too... > > All right, now what's different with my new is_numeric_* functions: > previously is_numeric_* ignored doubles that overflowed (INF), and returned > 0 -- think like 500 digits -- and the operands would be compared as strings. > So 2 strings that overflowed wouldn't wrongly be considered equal, I assume. > Now that's different with IS_DOUBLE being returned always, which is > appropriate for most cases like arithmetic. And it wasn't just overflown > numbers that previously returned 0, but underflown also ('1e-1000' or a VERY > small decimal number; they set ERANGE). > > I think the simplest way to keep the old behavior with the new is_numeric_* > is to use errno in zendi_smart_strcmp(). That'll make it a little slower, > but no slower on longs than the old version I don't think, and it'll still > be much faster with doubles/non-numeric strings. > > Any other thoughts on how it should be handled? That is the correct and > desired behavior to only compare numerically if both values can be > accurately represented? I'll update the patches ASAP once I find out what > to do... -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php