Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:80383 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 28667 invoked from network); 11 Jan 2015 22:12:48 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 11 Jan 2015 22:12:48 -0000 Authentication-Results: pb1.pair.com header.from=ajf@ajf.me; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ajf@ajf.me; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ajf.me designates 192.64.116.200 as permitted sender) X-PHP-List-Original-Sender: ajf@ajf.me X-Host-Fingerprint: 192.64.116.200 imap1-2.ox.privateemail.com Received: from [192.64.116.200] ([192.64.116.200:47790] helo=imap1-2.ox.privateemail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A1/A3-05184-F55F2B45 for ; Sun, 11 Jan 2015 17:12:47 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.privateemail.com (Postfix) with ESMTP id E5C4AB00092 for ; Sun, 11 Jan 2015 17:12:44 -0500 (EST) X-Virus-Scanned: Debian amavisd-new at imap1.ox.privateemail.com Received: from mail.privateemail.com ([127.0.0.1]) by localhost (imap1.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id BljUoui71Gvq for ; Sun, 11 Jan 2015 17:12:44 -0500 (EST) Received: from oa-res-26-240.wireless.abdn.ac.uk (oa-res-26-240.wireless.abdn.ac.uk [137.50.26.240]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.privateemail.com (Postfix) with ESMTPSA id 85B91B0007B for ; Sun, 11 Jan 2015 17:12:44 -0500 (EST) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Message-ID: Date: Sun, 11 Jan 2015 22:12:42 +0000 To: PHP Internals List Mime-Version: 1.0 (Mac OS X Mail 8.1 \(1993\)) X-Mailer: Apple Mail (2.1993) Subject: rand(), mt_rand() and limits From: ajf@ajf.me (Andrea Faulds) Hey internals, As we=E2=80=99re moving to clean some things up in PHP 7, I think it = might be worth looking at the rand()/mt_rand() situation. Currently, we have two standard-library functions to obtain a random = number: rand() and mt_rand(). rand() uses the C standard library = function, which on many stdlibs is slow or has a limited range (e.g. = Win32 rand()=E2=80=99s maximum return value is SHORT_MAX). As a result, = a drop-in replacement was added, mt_rand(), which uses Mersenne = Twister-based random number generator that=E2=80=99s probably better = than what the C standard library provides. Having two different random number functions is confusing to new users, = and an oft-cited issue with PHP=E2=80=99s standard library. Intuitively, = a user would expect rand() to be the function to get a random number, = but actually they should be using mt_rand(), which is usually better.=20 Another issue is the fact we allow random numbers to be seeded with = srand() and mt_srand(). We have automatically seeded the random number = generator for a while now, so there is no need to do it manually. We = also explicitly do not guarantee that the random number generator will = always produce the same output given the same seed, and in fact we=E2=80=99= ve changed mt_rand()'s behaviour in the past. This eliminates the = primary use-case for manual seeding when there is automatic seeding: = predictable output for procedural generation. Finally, a third issue is that mt_rand() does not produce good quality = numbers on 64-bit platforms. mt_rand() will always produce a 32-bit = value internally, and scale it up or down to fit the user-specified = range. Unfortunately, this means that values for the $max parameter = beyond 2^31 - 1 produce numbers with poor granularity. Given all these, I would suggest that for PHP 7, we: * Get rid of rand(), srand() and getrandmax() * Rename mt_rand(), mt_srand() and mt_getrandmax() to rand(), srand(), = and getrandmax() but add mt_* aliases for backwards-compatibility * Make mt_srand() and srand() do nothing and produce a deprecation = notice * Use a 64-bit random number generation algorithm on 64-bit platforms = (or invoke the 32-bit generator twice) The end result should be that PHP has just one random number generation = function, rand(), which can produce the full range from PHP_INT_MIN to = PHP_INT_MAX with no scaling. This would be far more intuitive, I think. Would that sound good? Thanks! -- Andrea Faulds http://ajf.me/