On Fri, 13 Apr 2012 11:48:10 +0200, Pierre Joye <pierre....@gmail.com>
wrote:
On Fri, Apr 13, 2012 at 11:40 AM, marius adrian popa <map...@gmail.com>
wrote:
Something for the weekend (flamewar)
http://www.reddit.com/r/programming/comments/s6477/9223372036854775807_9223372036854775808/
http://news.ycombinator.com/item?id=3832069
https://bugs.php.net/bug.php?id=54547
This conversation has become a quite muddled with usual controversies
about the nature of PHP. Instead of engaging in that sort of discussion,
I'll explain the situation.
Currently, when two strings are compared, PHP tries to do a numerical
comparison first. Therefore:
var_dump("010" == "10"); //true
The current implementation, however, gives up when the numbers are too
large or too small.
Zend/zend_operators.c
2049 /* Both values overflowed and have the
same sign,
2050 * so a numeric comparison would be
inaccurate */
var_dump("1.7976931348623157e308" ==
"1.79769313486231571e308"); //true
var_dump(1.7976931348623157e400); //INF
var_dump("1.7976931348623157e400" ==
"1.79769313486231571e400"); //false
In this case, a string comparison is done instead (memcmp).
There are other situations where the result of the comparison may be
"inaccurate" -- in the sense that two strings may be constructed as
representing different numbers, but they compare equal.
* Comparing two different real numbers that map to the same double
precision number:
var_dump("1.9999999999999999" == "2"); //true
* Comparing two integers that are not representable as ints and that map
to the same double precision number
var_dump("9223372036854775810" == "9223372036854775811"); //true
* Comparing an integer that's representable as an int with another that's
not. That is what the bug is about.
var_dump(PHP_INT_MAX); //9223372036854775807
var_dump("9223372036854775807" == "9223372036854775808"); //true
In this case, the integer is also converted to a double; if long is 64-bit
wide, this will result in loss of precision and now the operand will
compare equal.
These two last cases are easy to detect; I wrote a patch that does that
and forces a plain string comparison.
However, taking the last case an example, this is the same that happens if
you compare:
var_dump((int)"9223372036854775807" == (double)"9223372036854775808");
//true
So in that respect the current behavior is consistent with the comparison
that would take place if the numeric strings were to be converted to ints
or doubles (following the usual rules to choose between the two, i.e., if
there's no decimal place or exponent, take an int unless it's too large in
absolute value).
Whether the current behavior is correct depends on whether you consider
(string)"9223372036854775808" to represent an integer value that, not
being representable as int in PHP, should preclude a numeric comparison,
or if you consider (string)"9223372036854775808" to be the same as
(double)"9223372036854775808" for numeric comparison purposes. And I'm not
sure here.
--
Gustavo Lopes
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php