सी + + में यादृच्छिक डबल संख्या उत्पन्न करते हैं


83

कैसे सी + + में दो डबल्स के बीच यादृच्छिक संख्या उत्पन्न करने के लिए, इन नंबरों को xxxxx, yyyyy की तरह दिखना चाहिए।


6
"ये संख्या xxxxx, yyyyy जैसी दिखनी चाहिए"। यादृच्छिक डबल्स कैसे उत्पन्न करें, और स्ट्रिंग्स के रूप में डबल्स को कैसे प्रारूपित करें, पूरी तरह से अलग मुद्दे हैं।
स्टीव जेसोप

और इसके बारे में वैकल्पिक रूप से सोचें: समान रूप से वितरित डबल्स पैदा करना और समान रूप से वितरित डेसीमल उत्पन्न करना कुछ अलग हैं, हालांकि संबंधित, कार्य।
स्टीव जेसोप

समान रूप से वितरित पूर्णांक उत्पन्न करना दशमलव समस्या से अधिक निकटता से संबंधित है।
पोटैटोसवाटर

जवाबों:


116

ऐसे

double fRand(double fMin, double fMax)
{
    double f = (double)rand() / RAND_MAX;
    return fMin + f * (fMax - fMin);
}

जब भी आपका प्रोग्राम शुरू हो, उचित बीज के साथ सरंड () को कॉल करना याद रखें।

[संपादित करें] यह उत्तर अप्रचलित है क्योंकि C ++ को यह मूल गैर-सी आधारित यादृच्छिक पुस्तकालय है (देखें एलेसेंड्रो जैकोस्पॉन्स उत्तर देखें) लेकिन, यह अभी भी C पर लागू होता है


10
यदि आप RAND_MAX में 1 जोड़ते हैं, तो सावधानी से करें, क्योंकि यह INT_MAX के बराबर हो सकता है। double f = rand() / (RAND_MAX + 1.0);
स्टीव जेसोप

8
ध्यान दें कि इस की यादृच्छिकता सीमित हो सकती है। रेंज XXXXX, yyyyy 10 दशमलव अंकों का सुझाव देता है। बहुत सारे सिस्टम हैं जहाँ RAND_MAX 10 ^ 10 से छोटा है। इसका मतलब यह होगा कि उस सीमा में कुछ संख्याएँ हैंp(xxxxx,yyyyy)==0.0
MSalters

7
यदि संभव हो तो आपको रैंड () से बचना चाहिए। C ++ 11 या TR1 समाधान के लिए अन्य उत्तर देखें।
jfritz42

हर कोई C ++ 0x, tr1 या C ++ 11 का उपयोग नहीं करता है। क्या कोई संदर्भ है जो रैंड () दिखाता है, उससे बचा जाना है? यह दशकों से यादृच्छिक संख्या प्राप्त करने का एकमात्र तरीका है।
rep_movsd 15

1
@ChamilaWijayarathna, आपको cstdlib शामिल करने की आवश्यकता है
Veridian

103

इस समाधान के लिए C ++ 11 (या TR1) की आवश्यकता होती है।

#include <random>

int main()
{
   double lower_bound = 0;
   double upper_bound = 10000;
   std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
   std::default_random_engine re;
   double a_random_double = unif(re);

   return 0;
}

अधिक जानकारी के लिए जॉन डी। कुक की "सी ++ टीआर 1 का उपयोग करके रैंडम नंबर जेनरेशन" देखें

स्ट्रॉस्ट्रप की "रैंडम नंबर जेनरेशन" भी देखें ।


7
आप इसे और हाल ही के cppreference डॉक्यूमेंट के साथ अपडेट कर सकते हैं , जो बहुत अच्छा है।
शाफिक याघमोर

10

यह कई उपयोगों के लिए उपयुक्त, थ्रेड-सुरक्षित और लचीला होना चाहिए:

#include <random>
#include <iostream>

template<typename Numeric, typename Generator = std::mt19937>
Numeric random(Numeric from, Numeric to)
{
    thread_local static Generator gen(std::random_device{}());

    using dist_type = typename std::conditional
    <
        std::is_integral<Numeric>::value
        , std::uniform_int_distribution<Numeric>
        , std::uniform_real_distribution<Numeric>
    >::type;

    thread_local static dist_type dist;

    return dist(gen, typename dist_type::param_type{from, to});
}

int main(int, char*[])
{
    for(auto i = 0U; i < 20; ++i)
        std::cout << random<double>(0.0, 0.3) << '\n';
}

7

यदि सटीकता यहां एक समस्या है, तो आप महत्वपूर्ण बिट्स को यादृच्छिक करके एक महीन स्नातक के साथ यादृच्छिक संख्या बना सकते हैं। मान लें कि हम 0.0 और 1000.0 के बीच एक डबल करना चाहते हैं।

MSVC (12 / Win32) पर RAND_MAX उदाहरण के लिए 32767 है।

यदि आप सामान्य rand()/RAND_MAXयोजना का उपयोग करते हैं तो आपके अंतराल बड़े होंगे

1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...

IEE 754 डबल वैरिएबल्स (53 महत्वपूर्ण बिट्स) और 53 बिट रेंडमाइजेशन के मामले में 0 से 1000 समस्या के लिए सबसे छोटा संभव रैंडमाइजेशन गैप होगा।

2^-53 * (1000.0 - 0.0) = 1.110e-13

और इसलिए काफी कम है।

नकारात्मक पक्ष यह है कि रैंडम इंटीग्रल नंबर (15 बिट RNG मानकर) प्राप्त करने के लिए 4 रैंड () कॉल की आवश्यकता होगी।

double random_range (double const range_min, double const range_max)
{
  static unsigned long long const mant_mask53(9007199254740991);
  static double const i_to_d53(1.0/9007199254740992.0);
  unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 );
  return range_min + i_to_d53*double(r)*(range_max-range_min);
}

यदि मंटिसा या आरएनजी के लिए बिट्स की संख्या अज्ञात है, तो संबंधित मानों को फ़ंक्शन के भीतर प्राप्त करने की आवश्यकता होती है।

#include <limits>
using namespace std;
double random_range_p (double const range_min, double const range_max)
{
  static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1), 
    mant_limit(ll_one << num_mant_bits);
  static double const i_to_d(1.0/double(mant_limit));
  static size_t num_rand_calls, rng_bits;
  if (num_rand_calls == 0 || rng_bits == 0)
  {
    size_t const rand_max(RAND_MAX), one(1);
    while (rand_max > (one << rng_bits))
    {
      ++rng_bits;
    }
    num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits)));
  }
  unsigned long long r(0);
  for (size_t i=0; i<num_rand_calls; ++i)
  {
    r |= (unsigned long long(rand()) << (i*rng_bits));
  }
  r = r & (mant_limit-ll_one);
  return range_min + i_to_d*double(r)*(range_max-range_min);
}

नोट: मुझे नहीं पता कि अहस्ताक्षरित लंबे समय (64 बिट) के लिए बिट्स की संख्या सभी प्लेटफॉर्मों पर डबल मैन्टिसा बिट्स (आईईई 754 के लिए 53 बिट) की संख्या से अधिक है या नहीं। यह चेक शामिल करने के लिए शायद "स्मार्ट" होगा जैसे if (sizeof(unsigned long long)*8 > num_mant_bits) ...कि यह मामला नहीं है।


3

यह स्निपेट स्ट्रॉस्ट्रुप से सीधा है स्ट्रॉस्ट्रुप द सी ++ प्रोग्रामिंग लैंग्वेज (4 वें संस्करण) , .740.7 से सीधे है; इसे C ++ 11 की आवश्यकता है:

#include <functional>
#include <random>

class Rand_double
{
public:
    Rand_double(double low, double high)
    :r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){}

    double operator()(){ return r(); }

private:
    std::function<double()> r;
};

#include <iostream>    
int main() {
    // create the random number generator:
    Rand_double rd{0,0.5};

    // print 10 random number between 0 and 0.5
    for (int i=0;i<10;++i){
        std::cout << rd() << ' ';
    }
    return 0;
}

0

कुछ इस तरह:

#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    const long max_rand = 1000000L;
    double x1 = 12.33, x2 = 34.123, x;

    srandom(time(NULL));

    x = x1 + ( x2 - x1) * (random() % max_rand) / max_rand;

    cout << x1 << " <= " << x << " <= " << x2 << endl;

    return 0;
}

2
"(यादृच्छिक ()% max_rand)" = "यादृच्छिक ()" (यानी 3% 7 = 3)। यह एक व्यर्थ प्रसंस्करण कदम होगा।
जक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.