#22988 [Opn]: I'm feeling lucky - rand() bug
| From: | pollita@php.net | Date: | Fri, 18 Apr 2003 05:03:56 +0000 |
| Subject: | #22988 [Opn]: I'm feeling lucky - rand() bug | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-37836@lists.php.net to get a copy of this message | ||
ID: 22988
Updated by: pollita@php.net
Reported By: vakmajom at freemail dot hu
Status: Open
Bug Type: Math related
Operating System: Windows 2000
PHP Version: 4.3.2RC1
New Comment:
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.... :)
Previous Comments:
------------------------------------------------------------------------
[2003-04-17 11:06:09] 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-01 08:01:28] vakmajom at freemail dot hu
Sorry: srand((double)microtime()*100000);
------------------------------------------------------------------------
[2003-04-01 07:59:49] 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-03-31 17:49:50] sniper@php.net
Please try using this CVS snapshot:
http://snaps.php.net/php4-STABLE-latest.tar.gz
For Windows:
http://snaps.php.net/win32/php4-win32-STABLE-latest.zip
------------------------------------------------------------------------
[2003-03-31 15:22:49] 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...
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/22988
--
Edit this bug report at http://bugs.php.net/?id=22988&edit=1