c - रैंड()+रैंड() नकारात्मक संख्या क्यों उत्पन्न करता है?




random (6)

मैंने देखा कि rand() लाइब्रेरी फ़ंक्शन जब इसे लूप के भीतर एक बार कहा जाता है, तो यह लगभग हमेशा सकारात्मक संख्या पैदा करता है।

for (i = 0; i < 100; i++) {
    printf("%d\n", rand());
}

लेकिन जब मैं दो rand() कॉल जोड़ता हूं, तो उत्पन्न संख्याओं में नकारात्मक संख्याएं अधिक होती हैं।

for (i = 0; i < 100; i++) {
    printf("%d = %d\n", rand(), (rand() + rand()));
}

क्या कोई समझा सकता है कि मैं दूसरे मामले में नकारात्मक संख्या क्यों देख रहा हूं?

पुनश्च: मैं लूप से पहले बीज को srand(time(NULL)) रूप में आरंभ करता हूं।


जो कारण मैं जोड़ रहा था वह था '0' से बचने के लिए मेरे कोड में यादृच्छिक संख्या के रूप में। रैंड () + रैंड () त्वरित गंदा समाधान था जो आसानी से मेरे दिमाग में आया था।

एक सरल समाधान (ठीक है, इसे "हैक" कहें) जो कभी भी शून्य परिणाम नहीं देता है और कभी भी अतिप्रवाह नहीं होता है:

x=(rand()/2)+1    // using divide  -or-
x=(rand()>>1)+1   // using shift which may be faster
                  // compiler optimization may use shift in both cases

यह आपके अधिकतम मूल्य को सीमित कर देगा, लेकिन अगर आप उस बारे में परवाह नहीं करते हैं, तो यह आपके लिए ठीक काम करना चाहिए।


0 से बचने के लिए, यह प्रयास करें:

int rnumb = rand()%(INT_MAX-1)+1;

आपको limits.h शामिल करने की जरूरत है।


मूल रूप से rand() आपके मामले में 0 और RAND_MAX , और 2 RAND_MAX > INT_MAX बीच संख्या पैदा करता है।

आप अतिप्रवाह को रोकने के लिए अपने डेटा-प्रकार के अधिकतम मूल्य के साथ मापांक कर सकते हैं। यह संभोग यादृच्छिक संख्याओं के वितरण को बाधित करेगा, लेकिन rand त्वरित यादृच्छिक संख्या प्राप्त करने का एक तरीका है।

#include <stdio.h>
#include <limits.h>

int main(void)
{
    int i=0;

    for (i=0; i<100; i++)
        printf(" %d : %d \n", rand(), ((rand() % (INT_MAX/2))+(rand() % (INT_MAX/2))));

    for (i=0; i<100; i++)
        printf(" %d : %ld \n", rand(), ((rand() % (LONG_MAX/2))+(rand() % (LONG_MAX/2))));

    return 0;
}

यह इस उत्तर के लिए टिप्पणी में किए गए प्रश्न के स्पष्टीकरण का उत्तर है ,

जो कारण मैं जोड़ रहा था वह था '0' से बचने के लिए मेरे कोड में यादृच्छिक संख्या के रूप में। रैंड () + रैंड () त्वरित गंदा समाधान था जो आसानी से मेरे दिमाग में आया था।

समस्या से बचने के लिए 0. प्रस्तावित समाधान के साथ (कम से कम) दो समस्याएं हैं। एक है, जैसा कि अन्य उत्तर इंगित करते हैं, कि rand()+rand() अपरिभाषित व्यवहार को लागू कर सकता है। सबसे अच्छी सलाह है कि अपरिभाषित व्यवहार कभी न करें। एक और मुद्दा यह है कि rand() पंक्ति में दो बार 0 का उत्पादन नहीं करेगा इसकी कोई गारंटी नहीं है।

निम्नलिखित शून्य को खारिज कर देता है, अपरिभाषित व्यवहार से बचा जाता है, और अधिकांश मामलों में दो कॉलों की तुलना में अधिक तेज़ होगा rand() :

int rnum;
for (rnum = rand(); rnum == 0; rnum = rand()) {}
// or do rnum = rand(); while (rnum == 0);

हो सकता है कि आप यह सुनिश्चित करने की कोशिश कर सकते हैं कि 2 रैंड () के योग से लौटाया गया मान कभी भी RAND_MAX के मान से अधिक न हो। एक संभावित दृष्टिकोण योग हो सकता है = रैंड () / 2 + रैंड () / 2; यह सुनिश्चित करेगा कि 32767 के RAND_MAX मान के साथ 16 बिट कंपाइलर के लिए, अगर दोनों रैंड 32767 वापस करने के लिए होता है, तब भी (32767/2 = 16383) 16383 + 16383 = 32766, इस प्रकार नकारात्मक योग नहीं होगा।


rand() को 0 और RAND_MAX बीच पूर्णांक लौटाने के लिए परिभाषित किया गया है।

rand() + rand()

ओवरफ्लो हो सकता है। आप जो देखते हैं, वह पूर्णतः ओवरफ़्लो के कारण अपरिभाषित व्यवहार का परिणाम है।





random