php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #22988 I'm feeling lucky - rand() bug
Submitted: 2003-03-31 12:36 UTC Modified: 2003-08-12 19:58 UTC
From: vakmajom at freemail dot hu Assigned: pollita (profile)
Status: Closed Package: Documentation problem
PHP Version: 4.3.2RC1 OS: Windows 2000
Private report: No CVE-ID: None
 [2003-03-31 12:36 UTC] vakmajom at freemail dot hu
The function rand() always returns an even number!
This bug appears when the parameters of rand() are near to the limits of int (i.e. 2147483647)

Example:
<?php
 echo(rand(1, 2147483647));
?>
Result: always an even number.

I'm using Apache 2.0.44 with PHP4.3.2RC1 (original Win32 binary) as an apache module.

Tests with different systems:
Maybe this is a Windows bug, it still exists in Windows .Net server build 3718 with PHP 4.3.0 RC3
But everything is fine on a unix system with PHP 4.1.0

Strange... :))

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-03-31 15:22 UTC] pollita@php.net
This is being caused by a carryover (2147483647 + 1 == -2147483648).  

The short answer is: "If it hurts, don't do it!"

Of course that's not a proper answer.  The API Macro could probably use some tweaking...
 [2003-04-01 07:59 UTC] vakmajom at freemail dot hu
The same case. Only even numbers.

And a new rand() bug has also appeared:
Without srand(microtime()*100000), always the same 10-20 numbers are returned. You should try this bug after the restart of Apache, to be sure that none of the php scripts called srand() before.
 [2003-04-01 08:01 UTC] vakmajom at freemail dot hu
Sorry: srand((double)microtime()*100000);
 [2003-04-17 11:06 UTC] vakmajom at freemail dot hu
About the original bug...

Nothing has happened since April 1st, so i browsed the source code a little bit:
I think it is not just a carryover bug, it is more than that. It is because RAND_MAX on Windows, and RAND_RANGE.

The problem is the follownig: On Windows systems RAND_MAX is 32767, so only 32768 values can be returned if I call rand(1, 2147483647) from a PHP script. That's why rand(1, 2147483647) or rand(1, 65535) returns always an even number.
Maybe a RAND_MAX specific hack to the code: e.g. calling 
rand() three times and creating a 45 bit random value and then reducing it to a 32bit one, or somthing like that would help, but this would dirty the code...

Alright, let's use mt_rand(), it is a 31 bit random number on every system, and it is better than a 15 bit random number...
So if I call mt_rand(-2147483648, 2147483647) then I should get 2147483648 results. This is less than it should (4294967296), but more than 32768. 
And now, the suprise: the result is always the same:
-2147483648. This IS a carryover bug, and unless I am mistaken it can be solved by changing line 43 in file ext/standard/php_rand.h from 
(__n) = (__min) + (long) ((double) ((__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0)))
to
(__n) = (__min) + (long) ((double) ((double)(__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0)))
 [2003-04-18 00:03 UTC] pollita@php.net
I can see where you were going with that, unfortunately it has the unexpected result of simply chaning the bug so that only *odd* numbers get returned....

I'm still thinking over this one and hope you give it some more thought too.... :)

 [2003-04-26 16:55 UTC] pollita@php.net
After discussion it looks like PHP won't be getting into the business of fixing windows bugs :)

As you suggested the best bet is to stick with mt_rand() to get the resulution you're looking for.
 [2003-04-26 16:56 UTC] pollita@php.net
Actually the docs should mention this.  Reclassifying and opening back up.
 [2003-05-06 14:29 UTC] vakmajom at freemail dot hu
Why it is a Windows bug? Because RAND_MAX is not 2147483647?
Alrigth then.
But the documentation should also mention that you must not call rand(min, max) or mt_rand(min, max)
if (max-min > 2147483647) (on unix systems you get a Warning message (tested with PHP 4.1.0), but on Windows systems mt_rand(-2147483648, 2147483647) simply returns
-2147483648, without any warning message - as I explained.
 [2003-05-11 08:36 UTC] moriyoshi@php.net
changing to the correct status
 [2003-08-12 19:58 UTC] pollita@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 08:01:28 2024 UTC