2015-07-24 10 views
9

क्यों लौटाता है मैं हैकर न्यूज़ पर कंप्यूटरगुरु से interesting question पर आया हूं और कोई टिप्पणी एक ठोस जवाब देने के लिए प्रतीत नहीं होती है।mt_rand (1, PHP_INT_MAX) हमेशा एक विषम संख्या

mt_rand(1, PHP_INT_MAX) हमेशा एक विषम संख्या क्यों देता है?

मैं मूल प्रश्न का लेखक नहीं हूं।

http://3v4l.org/dMbat

for ($i=0;$i<10000;$i++) 
{ 
    echo mt_rand(1, PHP_INT_MAX)."\n"; 
} 

उत्पादन:

8571620074060775425 
7401021871338029057 
4351677773593444353 
1801559362708176897 
7848614552286527489 
... 
+5

शायद यह करने के लिए संबंधित, [mt_rand के लिए PHP मैनुअल पृष्ठ] (से लिया http: // php। नेट/मैनुअल/एन/function.mt-rand.php): * सावधानी: mt_rand() वापसी मानों का वितरण PHP के 64-बिट बिल्डों पर भी संख्याओं की तरफ पक्षपातपूर्ण है जब अधिकतम 2^32 से अधिक है।ऐसा इसलिए है क्योंकि यदि mt_getrandmax() द्वारा लौटाए गए मान से अधिकतम अधिक है, तो यादृच्छिक संख्या जेनरेटर के आउटपुट को स्केल किया जाना चाहिए। * – Simba

+4

क्योंकि PHP_INT_MAX> mt_getrandmax(), [अधिक जानकारी] (https: //www.reddit। कॉम/आर/lolphp/टिप्पणी/3eaw98/mt_rand1_php_int_max_only_generates_odd_numbers/ctdhxha)। – Sony

+2

http://assets.amuniversal.com/321a39e06d6401301d80001dd8b71c47 – j08691

उत्तर

5

यहाँ -1 (64-बिट पर हस्ताक्षर किए पूर्णांक अधिकतम) है।

हालांकि, mt_rand() इस बड़े मूल्य को संभाल नहीं करता है। मेर्सन ट्विस्टर आंतरिक रूप से 32-बिट शब्दों को उत्पन्न करता है, और PHP का mt_getrandmax() केवल 2 -1 (यह उच्चतम बिट को फेंक देता है)।

अपने minmax श्रृंखला के लिए अनुरोध किया है, mt_rand पहले 0 2 के लिए -1 यादृच्छिक संख्या हो जाता है में एक मूल्य उत्पन्न करने के लिए है, तो यह इस सूत्र का उपयोग तराजू:

x = ((x/(mt_getrandmax() + 1)) * (max - min + 1)) + min; 

(का स्रोत देखें rand.c और php_rand.h।)

असल में यह अंधेरे से आंतरिक रूप से जेनरेट किए गए नंबर को बड़े पैमाने पर फिट करने के लिए स्केल करता है, बिना किसी चेतावनी को उठाए। ओवरलैज रेंज फिट करने के लिए गुणा करने से कम बिट्स में बहुत सारे शून्य उत्पन्न होते हैं, फिर min (जो 1 है) जोड़ना परिणाम अजीब बनाता है।

for ($i = 0; $i < 10000; $i++) { 
    printf("%016x\n", mt_rand(1, PHP_INT_MAX)); 
} 

आउटपुट::

41e0449b00000001 
53d33d7c00000001 
6ec8855700000001 
234140e000000001 
13a4581900000001 
77547beb00000001 
35a0660a00000001 
0d0cd44200000001 
... 

है

समस्या हेक्साडेसिमल, जिनमें आप उस प्रत्येक संख्या का कम 32 बिट पूरी तरह से गैर यादृच्छिक देख सकते हैं में अधिक नाटकीय है एक नोट in the manual जो इस बारे में चेतावनी देने का प्रयास करता है, हालांकि यह समस्या को कम करता है:

mt_rand() का वितरण max से परे PHP के 64-बिट बिल्डों पर भी संख्याओं की ओर पक्षपातपूर्ण है। ऐसा इसलिए है क्योंकि maxmt_getrandmax() द्वारा लौटाए गए मान से अधिक है, तो यादृच्छिक संख्या जनरेटर का आउटपुट स्केल किया जाना चाहिए।

(इसे कहते हैं तो यह और भी संख्या के प्रति पक्षपाती है, लेकिन जब min भी है कि केवल सच है।)

+1

ग्रेट स्पष्टीकरण, धन्यवाद। अजीब है कि अगर आप इसे mt_getrandmax() 'के बजाय मान मानते हैं तो PHP त्रुटि/अपवाद नहीं फेंकता है। – ceejayoz

संबंधित मुद्दे