I had made a Pong game where I had to randomize the throw of the ball. To do this, I used the inbuilt random number generator and got good results in Ubuntu/GCC. On porting the code to Mac and compiling, the ball would only be projected in a single direction, meaning that the rand()
function in clang was not working as expected.
I have since reverted to a custom number generator, but here's the original problematic code in the game:
srand(time(NULL));
float ang = ((float)rand())/RAND_MAX * 120 - 60;
int side = (int)(((float)rand())/RAND_MAX * 2);
Upon further inspection, I created the following test program and compiled and ran it on both platforms.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
while (1) {
int now = time(NULL);
printf("Time now is %d\n", now);
srand(now);
int random = rand();
printf("Random number generated is %d\n", random);
sleep(1);
}
}
The results (tabulated and calculated against RAND_MAX
, which is 2147483647
on both systems) are as follows:
The results speak for themselves. While there is randomness in the clang version, as compared to the value of RAND_MAX
, the randomness is very poor and is evidenced by the standard deviation of 0, compared to the standard deviation of 0.328 on gcc.
What are the reason(s) for this poor behaviour of rand()
on clang ? I would also like to see the reference implementation of this function in the header file. This seems nonstandard, and I must not be the only one who ran into problems while porting programs using this method to Mac. What other design principles are good practice while using/relying upon random number generators?
So I don't know the exact implementation for apple's clang implementation for rand, however I know it was done as a LCG, or Linear Congruential Generator. The way it works is basically a formula:
In the formula, would be the
RAND_MAX
, and
are some constant defined by the compiler. Apple's Clang used
16807
and 0
respectably.
The return for rand()
is , and last return of
rand()
or the value you put in srand()
would be .
If you just want a sequence of number, that are kinda random, this works pretty well, as it would eventually return all numbers between 0
and RAND_MAX
, without a noticeable pattern by human.
However, with some calculations, you can easily spot it would have some problem if you just put a continuous sequence of number in the place ofin that formula (which is what you did). The difference between each call of
rand()
would be exactly equals to , except when
is actually close to
RAND_MAX
.
The correct ways of getting random number through rand()
function is only calling srand()
once at the beginning, and use only rand()
in the loop.
Alternatively, there are many other random generating formula you could look for, and you can probably find some here: How to generate a random int in C?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.