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

Reply via email to