On Sun, 13 May 2012 04:39:33 +0200, Stas Malyshev <smalys...@sugarcrm.com>
wrote:
I know this was discussed a number of times here, but just to bring it
to a conclusion - I intend to apply patch in the bug report - which
removes conversion for strings that do not convert to integers - to 5.4.
If anybody sees anything that breaks because of this please tell. Not
sure what about 5.3 - Johannes, could you please comment?
I've run the tests and the patch does not seem to cause any breakage.
I should point out that "remove[ing] conversion for strings that do not
convert to integers" (let's call it proposition A) is not exactly what the
patch does. In addition to that condition, one other is required:
* The floats a and b the strings convert to are such that a - b == 0.0 (B)
It's implemented as
if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) { ... }
This is irrelevant for == or != comparisons. Let's call C "strings are
equal in the memcmp() sense". If only A is evaluated, then if ~A, the
result of the comparison is the value C, i.e., if strings do not convert
to integers, the result of the comparison is the result of memcmp(). Also
under ~A, if we add B into the mix, we have the following results:
B ~B
C 1 can't occur
~C 0 0
But for the comparisons >, <, etc. the result may be surprising. Under ~A
&& ~B && ~C, using only the first condition results in a memcmp()
comparison, while under the two comparisons results in the floats being
compared. See:
$ php -r 'var_dump(strcmp(" 9223372036854775809",
"-9223372036854775808"));'
int(-1) (str1 is less than str2)
$ php -r 'var_dump((float)" 9223372036854775809" <
(float)"-9223372036854775808");'
bool(false)
So the float comparison behavior under ~B (what's in the patch) may seem
more desirable because it preserves the numerical comparison when possible
(and we don't have to add leading whitespace and zeros to the mix,
strcmp("9, "11") returns 1). Until you realize it's alternating between
two behaviors depending on whether B or ~B. So:
"9223372036854775809" < " 09443372036854775809" (true, -- floats differ,
compare as float)
"9223372036854775809" < " 09223372036854775810" (false -- floats are the
same, memcmp)
In both cases (incorporating the test for B or not), there's no escaping a
discontinuity in behavior, unless we revert not to memcmp() but to a
custom string comparison function that strips whitespace and leading
zeros, compares the size of the input and finally calls memcpy().
--
Gustavo Lopes
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php