## rand(); isn't random

7 posts / 0 new
Author
Message

I'm trying to generate a random number between 0 and 9

i've used the following different methods

```(int)((double)rand() / ((double)RAND_MAX + 1) * N)

rand() / (RAND_MAX / N + 1)

rand() % N /* POOR */ ```

i use N = 10 to get 0 - 9 random numbers..

well i'm not getting random numbers i'm always getting the same number..

any ideas?

Take a look at the avr-libc manual.
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ge23144bcbb8e3742b00eb687c36654d1
The rand() function returns a 16 bit sized integer value.

Quote:

`(int)((double)rand() / ((double)RAND_MAX + 1) * N)`

This expression is alwys zero since
the divisor is always greater than the dividend.

Quote:

`rand() / (RAND_MAX / N + 1)`

This expression will result in most cases zero, too.
Only if the random number is greater or equal
than the expression (RAND_MAX / N + 1) the result
would be greater than zero.

Try to avoid any division and modula operation whenever possible. They need extensive calculation time. Better use bit-masks:

```uint8_t randNumber;

randNumber = (uint8_t) rand();  // Get a random number (0 to 255)
randNumber = randNumber & 0x0F; // Set number range to  0 to 15

if (randNumber > 9)             // Set number range to 0 to 9
randNumber -= 6;```

Please note that you will always get the same numerical order
as long you use the same seed for the rand() function.

Regards
Sebastian

is there a way to make the seed random?

You need to inject some entropy into the system for random numbers. As it stands the Psuedo Random Number Genertaor (PRNG) is exactly what it says "Psuedo Random". That is a mathemtical formula that cycles through a range of numbers in an "odd" order but it's completely predictable. To introduce some unpredictability you need to find a real world source of randomness. If, for example, your chip has an external clock connected then some mix of the current date/time can often be used to inject a "random" seed into the AVR when it's first powered on. Another way to do is, for example, if the AVR has "user buttons". From power on start a milli/microsecond timer and each time a button is pressed take the current timer count as a seed for the PRNG. The chances of the user pressing the button at EXACTLY the same microsecond from power on are probably pretty remote. Another way is to use a "noisy" diode to inject some noise into the AVR - a thread search here will tell you more about that.

But the bottom line is that you need to inject some external "randomness" (aka "entropy")

(oh, on Linux machines another entropy source that feeds into /dev/random besides keyboard and mouse movement is the time between Ethernet packets on the network interface)

Cliff

Thanks,

i think i'm just going to start a timer and read it when my button is pressed..

thanks