#18773 [Ctl->Csd]: Quicksort result is different between Windows and Unix.
| From: | zeev@php.net | Date: | Tue, 20 Aug 2002 18:12:25 +0000 |
| Subject: | #18773 [Ctl->Csd]: Quicksort result is different between Windows and Unix. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-17328@lists.php.net to get a copy of this message | ||
ID: 18773
Updated by: zeev@php.net
Reported By: rgaidot@swt.fr
-Status: Critical
+Status: Closed
Bug Type: Arrays related
Operating System: Windows 2000 Pro
PHP Version: 4CVS-2002-08-07
New Comment:
Ok, technical background first:
This bug has to do with several facts:
1. PHP performs numeric comparison between strings that 'look like
numbers'. For instance, 000000073 is a string that looks like a
number. A numeric comparison will be performed if and only if both of
the compared strings look like numbers.
2. In the implementation of this functionality, the C library function
strtod() is used.
3. strtod() recognizes exponential notations, so 000000E2 is actually
0.0E+2, or 0.
4. Under Windows, the letter 'D' is also recognized as the exponent
sign so 000000D2 is also 0.0E+2. Don't ask me why, but it's clearly
documented in MSDN :)
The 4th point is the source of the difference between the behavior you
see under UNIX and the one you see under Windows. Try changing the
'000000D2' element to '000000E2', and you should see identical behavior
under UNIX too (haven't tested it, but I'm pretty sure this would
happen).
Solution? There's an easy one, and a difficult one.
Easy one - add a letter (other than A-F) in the beginning of each
element you wish to sort on. For intsance, if you start any string
with 'S' or 'Z', PHP will not mistake it for a numeric string.
Drawback - you may not be in control of the data, so it may not work.
Complex one - implement the comparison function yourself, and if both
elements are strings, call strcmp() instead of using >=. You would
also have to implement array comparison yourself so that it calls your
comparison function recursively. If you use the built-in >= operator,
it will use the numeric-string aware comparison function.
I hope you're not lost, and I hope this helps :)
Previous Comments:
------------------------------------------------------------------------
[2002-08-20 13:59:04] zeev@php.net
Ok, almost :)
<?php print_r(sort(array('0D2', '004'))); ?>
------------------------------------------------------------------------
[2002-08-20 13:55:39] zeev@php.net
Reduced to:
<?php print_r(array('0D2', '004')); ?>
Further details soon...
------------------------------------------------------------------------
[2002-08-08 08:31:26] kalowsky@php.net
I'd like to mark this as critical because my local tests show:
MacOSX results:
Sort 1 Sort 2
1 5
2 3
3 4
4 2
5 1
Win2000 results:
Sort 1 Sort 2
1 1
2 3
3 4
4 5
5 2
Neither sort went over correctly.
------------------------------------------------------------------------
[2002-08-07 05:02:12] eru@php.net
reclassified, updated version, verified
------------------------------------------------------------------------
[2002-08-07 04:46:18] rgaidot@swt.fr
I have tried to use the sort function on a string array. The array
strings include both integer and char characters.
(e.g. 0000AER, 000000S0, 00000073)
I have noted that the result differs between the two systems Windows
and Unix. Indeed the result on Unix is correct, but it is not correct
on Windows.
I have made a C++ test application in order to compare the results
between the two systems and I did not note any problem.
<PHPScript_Test>
$a=array(
array('000000S0','1','5'),
array('000000O2','2','4'),
array('000000D2','3','3'),
array('000000MH','4','2'),
array('00000073','5','1')
);
echo "<h1>Data</h1>";
echo "<pre>";
var_dump($a);
echo "</pre>";
sort($a);
echo "<h1>Result</h1>";
echo "<pre>";
var_dump($a);
echo "</pre>";
</PHPScript_Test>
Thanks,
Régis Gaidot
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=18773&edit=1