Random Number Generator

I have this function to generate a random number seeded at the time of the computer, and I use this function several times with the same parameters. However, since the code is compiled at the same time, I end up receiving the same "random" number for each of its output. Any suggested adjustments would be greatly appreciated.

1
2
3
4
5
6
7
8
9
10
  int randNumGenerator(int lowNum, int highNum) {
        int randNum;

        srand(time(0));

        randNum = (rand() % highNum) + lowNum;

        return randNum;

    }
The srand() function should only be called once, usually early in main().
are you allowed to use <random> which has the ability to generate in a range and provide more flexible settings across the board?

time(0) is probably using miliseconds, and if you called that in say a loop, it is likely that it would get the same seed each time. If you put a sleep(2) in the calling loop, it would probably fix it. This is not the way to do it; it is an explanation of what is probably going on. The above (do srand once only) is the right answer.
Don’t let people bully you into using rand() and modulo. Use the modern C++ random library.

M E T H O D   O N E

No seeding necessary. Always random:

1
2
3
4
5
6
#include <random>

int random( int min, int max )
{
  return std::uniform_int_distribution<>( min, max )( std::random_device{}() );
}

M E T H O D   T W O

If you wish to have a PRNG with a controllable seed, you’ll need to set that up properly:

1
2
3
4
5
6
7
8
#include <random>

std::mt19937 rng( std::random_device{}() );

int random( int min, int max )
{
  return std::uniform_int_distribution<>( min, max )( rng() );
}

Yep, that there global is NOT evil.
Use any PRNG you wish on line 3.
If you wish to re-use a specific seed (so that your program does the same thing every time — good for debugging), then use it in place of the random_device.

If you are using C then you might want to look at this thread:
http://cplusplus.com/forum/general/282260/#msg1221435

Good luck!
time(0) is probably using miliseconds

time(0) is pretty much always in seconds these days.
Note that the C++ clock's .count() are in nanoseconds.

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;

int main() {
    cout << time(0) << '\n';
    cout << chrono::system_clock{}.now().time_since_epoch().count() << '\n';
}

1
2
3
Output: 
1646153972
1646153972083720066

time(0) is probably using miliseconds

cppreference has this to say on the C library time function:
The encoding of calendar time in time_t is unspecified, but most systems conform to POSIX specification and return a value of integral type holding the number of seconds since the Epoch.

https://en.cppreference.com/w/c/chrono/time

The C++ version of the C library time function says it somewhat differently, but time() is still measured in seconds.

Not that it really matters but time() can return -1 if the system time wasn't retrieved the return type is usually a signed arithmetic type. srand() wants an unsigned int as input, so without casting time() the compiler can complain with a warning.

Using the C library's srand()/rand() in C++ code isn't wrong, they just have issues. Especially when combined with using % to generate a random number within a range.

https://web.archive.org/web/20180123103235/http://cpp.indi.frih.net/blog/2014/12/the-bell-has-tolled-for-rand/

C++ has the <random> library, so any C++ code should use the C++ random facilities.

https://en.cppreference.com/w/cpp/numeric/random

What <random> adds to the coding toolbox is almost an embarrassment of riches, so many engines to choose from, each one using a different mathematical algorithm to generate a sequence of psuedo-random numbers.

Plus there are numerous distributions that replace the modulo clamping. Uniform for integers and floating point numbers so any number in the provided min-max range has as much of a chance to be chosen as any other. Other distributions for other statistical outcomes. A normal distribution is one that can produce the "bell curve" with the probability any given random number is more likely to be in the middle of the range.

The C++ standard has a number of predefined random number generators, with the ability to create others as needed.

Using the C++ random engines seems to be more complicated since there are so many choices available. Here's an older C++ working paper that is a good introduction, it helps demystify the usage:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf
1)
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <ctime> // for time()
using namespace std;
 
int main(){
    
    srand(time(0)); // set initial seed value to system clock
    int low=10, high=20;
    cout << (rand()%(high-low+1))+low << "\n"; // Generate a random number between low and high (inclusive)    

}


2)
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <random>

int main (){	
	std::minstd_rand func (time(0));
	for(int i=0;i<10;i++){
	    std::cout <<func() << "\n";
	}

}
@anup30
Do you like going backwards?
It really helps to read the thread before posting.
Topic archived. No new replies allowed.