Srand() function


(Catriona) #1

OK this is probably a stupid question but in Crait’s tutorials, lesson 4, when we are making a random number generator and trying to guess the number he adds the following code to the setup.

srand(7/8);
randomnumber = 1 + rand() % 100;

now I believe the second line is setting randomnumber with a randomly selecting a number limited by modulus 100 (i.e. 0=99) and adding 1 to make it a number between 1 and 100 ,

but what is srand(7/8) about??


Pixel drawing app
(Kea Oliver) #2

No expert but srand “seeds” the random number generator, gives it something to work from. With the same seed rand will give predictable results (ie, the same)


(Catriona) #3

yeah, that means literally nothing to me. can you tell me what the 7/8 in the brackets is doing?


(Kea Oliver) #4

Thats the seed, you just give it a value, in this case he is using 7/8 . Sorry that I cant answer why specifically that value but theoretically you could use 1, 23142, 47, the current time, etc


(Catriona) #5

ok, but for clarity. with the statements he has:

srand(7/8);
randomnumber = 1 + rand() % 100;

what range of numbers would you get?


(Kea Oliver) #6

rand()% 100 would give 0-99, he adds 1 to make it between 1-100. rand returns a number usually between 0 and RAND_MAX. Using the module is to constrain it to give values in the range you want. You could do the same thing by using the Arduino random function (random(min,max))


(Scott) #7

With Arduino and the Arduboy, it’s better to use:

arduboy.initRandomSeed();
randomnumber = random(1, 101);

(Catriona) #8

Thanks guys. After doing some reading on seeded random number generation I think what you said makes more sense.

The srand() sets the seed, or starting point, for the rand() function. If you don’t declair it then you are effectively setting the seed to 1.


(Steven A) #9

And typically your results would always be the same, unless you seed the generator. :slight_smile:


(Scott) #10

And if you use srand(7/8) you’ll be using the same seed each time you start the program, so you’ll get the exact same sequence of pseudo-random numbers.

arduboy.initRandomSeed(); will seed the random number generator with a random value, so it will start at different points, thus giving a different sequence each time the program is started.


(Catriona) #11

Thanks Scott, that makes perfect sense now.


(Pharap) #12

I’m guessing that’s a mistake.

Using integer arithmetic 7 / 8 is 0, and 0 is a value you shouldn’t pass to srand because it upsets a lot of PRNGs.

(There’s a lot of things I don’t like about the tutorials.)


Other people have explained the basic idea, but I want to give a deeper explanation that will hopefully make things clearer. (You’ll probably already know some of this is you started reading about them,
but it might be useful to others as well.)

The kinds of ‘random number generators’ used in programming usually aren’t actually random,
they’re actually pseudo-random, which means they’re generated with an algorithm.

They tend to start with a ‘seed’ value and apply a particular operation to that seed to get their first value,
and from then on they just keep reapplying the same operation.

For example, let’s say we had the worst PRNG in the world and the operation was state + 1.
If you passed in 8 as the seed, the first value you’d get back is 9, and then 10 and then 11 et cetera,
because each time the PRNG is just applying the same operation to the internal state and giving you that value.

The state + 1 thing is a bit of a simplification.
A more realistic example would be (((state * multiplier) + increment) % modulus),
(where multiplier, increment and modulus are constant values),
which is what a linear congruential generator does.

LCGs are actually notoriously bad random number generators because there’s actually a pattern to the numbers they produce, but it’s hard to spot unless you’re looking, and they’re a good introduction to PRNGs.
(All the good PRNGs are far more complicated.)

Some of the more advanced PRNGs are a lot more complex and have several different parts to their state.
The one used by Arduino is relatively simple and probably not very ‘random’ statistically,
but it’s probably good enough for general use and certainly good enough for games.


Since random has been mentioned, there are three differences between rand and random:

  • rand returns an int (16-bits on Arduboy/AVR), random returns a long (32-bits on Arduboy/AVR)
  • random is a non-standard function (and it isn’t available on some Arduino-compatible chips), but rand is part of the C standard library
    • The Arduboy is actually programmed with C++, but most of the Arduino libraries are actually C libraries for some reason
  • rand doesn’t accept any arguments, it just returns a value, whilst random has three variants, one that takes no arguments, one that takes an exclusive upper bound and one that takes an exclusive upper bound and an inclusive lower bound

(Scott) #13

I’d argue that the worst PRNG in the world would be operation: 1. :stuck_out_tongue_winking_eye:


(Pharap) #14

Nine


(Kea Oliver) #15

Damn Pharap swooping in with the knowledge bomb. I knew most of this but this is some good info! Appreciated.