How to get a larger random number from the c function rand()

前端 未结 4 1914
孤独总比滥情好
孤独总比滥情好 2021-01-19 21:19

I am in a coding environment where I only have access to some most basic c functions. #include\'ing other lib is not feasible.

In this environment, I can call rand()

相关标签:
4条回答
  • 2021-01-19 21:36

    rnum = (rand() << 15) | rand() might be faster, but if you need good quality random numbers you should look for an external library. Built-in random functions are generally adequate only for the simplest applications.

    0 讨论(0)
  • 2021-01-19 21:46
    static unsigned long next = 1;
    int my_rand(void) {
        next = next * 1103515245 + 12345;
        return((unsigned)(next/65536) % (RAND_MAX+1));
    }
    
    void my_srand(unsigned int seed) {
        next = seed;
    }
    

    on linux

    #define RAND_MAX    2147483647
    

    your environment RAND_MAX is probably 32767

    reference: http://en.wikipedia.org/wiki/Linear_congruential_generator

    if you are not memory constrained you can look also at http://en.wikipedia.org/wiki/Mersenne_twister the code is embeddable as like as the example above

    0 讨论(0)
  • 2021-01-19 21:46

    Before using ANY random number generator for a non-trivial use, it should be tested extensively. Here is a link to one article on this subject.

    A fun background on the weaknesses of even true random numbers is available in the various histories on the code-breakers at Bletchley Park in WWII. The Germans and Hitler for most of the war assumed their codes were unbreakable because of being encrypted with random numbers, whereas the British were breaking all of these codes completely within months because of various weaknesses in the German implementation of "randomness". Many codes were sufficiently "twisted", if not outright broken, within a few days or months, sufficiently to be of use even though not completely broken.

    0 讨论(0)
  • 2021-01-19 21:58

    Besides the other excellent solutions proposed here, you can also do a power expansion in RAND_MAX, truncate at a user defined MY_RAND_MAX, and discard solutions which would cause uniformity to be destroyed.

    int myrand(int MY_RAND_MAX)
    {
        int j = 0, num = 0;
    
        // Generate digits for expansion in powers of RAND_MAX, up to acceptable range.
        while (pow(RAND_MAX + 1, j) <= MY_RAND_MAX){
            num = num + rand() * (int)pow(RAND_MAX + 1, j);
            j++; 
        } 
    
        //compute remainder to determine truncation 
        int remainder = ((int)pow(RAND_MAX + 1, j)) % (MY_RAND_MAX + 1); 
    
        // If number is within accepted bounds, mod and return
        if (num <= (  (int)pow(RAND_MAX + 1, j) - remainder ) ){
            return (num % (MY_RAND_MAX + 1)); 
    
        // Else, if number generated exceeds allowed bounds, rerun method.
        }else if (num > (  (int)pow(RAND_MAX + 1, j) - remainder ) ){
            return myrand(MY_RAND_MAX);
    
        }else{
            exit(-1);
        }
    }
    

    You can check empirically that this method gives you a statistically uniform output in the given range.

    I've done so for several trials with different ranges, each with a sample size of 100000, and got an agreement between the variance of the sample and the expected variance to at least 3 sig. fig.s each time.

    p.s. I am not a coder, but a mathematician/physicist who has recently learnt to code, so any and all feedback on the quality of my code would be appreciated.

    0 讨论(0)
提交回复
热议问题