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

I am in a coding environment where I only have access to some basic c elements. #including'ing another lib is not possible.

In this environment, I can call rand (), which gives me a random number from 0 to 32767 inclusive (I think) in my environment. Is the following code the correct logic to get a larger random number that is evenly distributed like / like rand ()?

rnum = rand() * (32767 + 1) + rand();

+4
source share
4 answers

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

+5
source
 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; } 

in linux

 #define RAND_MAX 2147483647 

your environment is RAND_MAX, probably 32767

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

if you are not limited by memory, you can also see http://en.wikipedia.org/wiki/Mersenne_twister the code is embedded, as in the example above

+2
source

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

An interesting background on the weaknesses of even true random numbers is available in various stories on combination locks in Bletchley Park in World War II. The Germans and Hitler throughout most of the war assumed that their codes were unbreakable due to random number encryption, while the British completely violated all these codes for several months due to various weaknesses in the German implementation of "randomness". Many codes were sufficiently "twisted", if they were not completely broken, within a few days or months, enough to be useful, although not completely broken.

0
source

In addition to the other excellent solutions offered here, you can also increase the power in RAND_MAX, truncate with the help of the user MY_RAND_MAX, and discard solutions that could lead to disruption of uniformity.

 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 empirically verify that this method gives you a statistically uniform output in a given range.

I did this for several tests with different ranges, each with a sample size of 100,000, and I got agreement between the sample variance and the expected variance of at least 3 sig. everytime.

ps I'm not a coder, but a mathematician / physicist who recently learned to code, so any feedback on the quality of my code will be appreciated.

0
source

All Articles