php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #18773 Quicksort result is different between Windows and Unix.
Submitted: 2002-08-07 04:46 UTC Modified: 2002-08-20 14:12 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: rgaidot at swt dot fr Assigned:
Status: Closed Package: Arrays related
PHP Version: 4CVS-2002-08-07 OS: Windows 2000 Pro
Private report: No CVE-ID: None
 [2002-08-07 04:46 UTC] rgaidot at swt dot 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

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-08-07 05:02 UTC] eru@php.net
reclassified, updated version, verified
 [2002-08-08 08:31 UTC] 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-20 13:55 UTC] zeev@php.net
Reduced to:
<?php print_r(array('0D2', '004')); ?>

Further details soon...
 [2002-08-20 13:59 UTC] zeev@php.net
Ok, almost :)

<?php print_r(sort(array('0D2', '004'))); ?>

 [2002-08-20 14:12 UTC] zeev@php.net
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 :)
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon May 27 11:01:28 2019 UTC