Formula used for function rand() in c++ - c++

I want to know what is the formula used for generating random numbers using the rand() function in C++. At first I though it would return random numbers every time, but it does not.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
srand(9865);
cout << rand() << "\n";
return 0;
}
Here I thought that, maybe because of given seed number and that unknown formula, it will be showing same number.
But, when i removed "srand(9865);" and execute several times it is showing only "41" as output. Please explain me what is all going on here.

From http://linux.die.net/man/3/rand
"If no seed value is provided, the rand() function is automatically seeded with a value of 1. ", and "..These sequences are repeatable by calling srand() with the same seed value. "

You have to seed your random function with a non static seed every time. One simple but not so accurate solution is to seed it with the clock:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
srand(time(NULL));
cout << rand() << "\n";
return 0;
}

The library specifications don't dictate the formula for the random number generator (it is up to the implementation). The only things specified are that things can be controlled via srand for consistent pseudo-random generation:
In order to generate random-like numbers, srand is usually initialized to some distinctive runtime value, like the value returned by function time (declared in header <ctime>). This is distinctive enough for most trivial randomization needs.
So:
If you initialize srand with a given seed, the following rand calls will be consistent across runs.
If you initialize srand with a time-based seed, the following rand calls will almost surely be different across runs.
If you do not initialize srand, the following calls to rand will use the default initial seed.
Note that in contemporary C++, you should avoid using these ancient functions. See the answers to this question.

Related

How do I display a random element of a vector? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I am trying to display "first", "among", "shift", "debug", and "craft" randomly, but it prints "shift" every time I run the project. In case this has anything to do with my problem, I'm using Xcode on macOS Ventura.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector <string> vec {"first", "among", "shift", "debug", "craft"};
int rand_num = rand() % vec.size();
string word;
word = vec[rand_num];
cout << word;
return 0;
}
I expected it to display "first", "among", "shift", "debug", or "craft" randomly, but it only printed "shift"
The rand() function gives a random value between 0 and RAND_MAX which will be same every time you run the program unless you seed it using the srand() function. Your code does not use srand() so rand_num is initialized with the same value every time you run the program.
rand() generates a pseudo-random sequence of numbers that will be the same given the same seed. Since you aren't explicitly initializing the seed using srand, you keep getting the same random value.
One way of initializing it so it gets a different seed in each execution is to use the current time:
// Must be called before you call rand:
srand (time(NULL));

Why does my functions generate always the same "randomness"? [duplicate]

This question already has answers here:
Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?
(5 answers)
Closed 11 months ago.
I thought that the shuffle_string function would have generated a new seed each time gets called (so every time the cycle repeats), but something is wrong.
What could I do to circumvent this problem?
(COMPILER: g++, OS: Windows 10 x64)
Edit:
Compiling with Visual Studio my code is actually running as expected.
Edit2:
As suggest in the comments by #Eljay , adding 'static' before
std::random_device rd;
and before
std::mt19937_64 mt64{ rd() };
makes my program run fine even if comping with g++.
#include <iostream>
#include <random>
using std::cin; using std::cout;
void shuffle_string(std::string& s) {
auto size = s.size();
std::random_device rd;
std::mt19937_64 mt64{ rd() };
std::uniform_int_distribution<unsigned long long int> ind_range (0, size-1);
for (auto i = 0; i < size; ++i) {
std::swap(s[i], s[ind_range(mt64)]);
}
}
int main() {
while (true) {
std::string string;
cout << "Enter the string you want to randomly shuffle:\n";
std::getline(cin, string);
if (string == "exit") { return 0; }
shuffle_string(string);
cout << string << '\n';
}
}
P.S.: I know i should always prefer std::shuffle, but i'm writing this only with the aim of learn something new (and actually this problem is something new).
Thanks, good evening.
The problem is that you call the default constructor for std::random_device in this line:
std::random_device rd;
Calling the default constructor gives you a std::random_device with an implementation-defined token as source.
According to the c++ reference for std::random_device (emphasis mine)
std::random_device may be implemented in terms of an
implementation-defined pseudo-random number engine if a
non-deterministic source (e.g. a hardware device) is not available to
the implementation. In this case each std::random_device object may
generate the same number sequence.
Hence it is allowed by the standard that your call to the default constructor gives a std::random_device that always give the same series of random numbers.
Next, given a initial seed for the Mersenne Twister random seed, you always get the same series of numbers.
This is why your program always give the same results.
You can fix this issue by giving to the constructor of std::random_device a specific token, for example
std::random_device rd{"/dev/urandom"};
Notice that the specific tokens available are implementation-dependent.

c++ program not working in code block IDE

i have a simple C++ program to generate uniform distributed random numbers, the program is working properly in visual studio. but when i run it in the code block IDE i get repeated random number, how can i fix that pleas?
#include <random>
#include <functional>
#include <ctime>
#include<iostream>
using namespace std;
double Rand()
{
random_device seeder;
const auto seed = seeder.entropy() ? seeder() : time(nullptr);
mt19937 eng(static_cast<mt19937::result_type>(seed));
uniform_real_distribution<double> dist(0, 1);
auto gen = bind(dist, eng);
return gen();
}
int main()
{
srand((unsigned)time(0));
for (unsigned int i = 0; i < 10; ++i)
cout<<Rand()<<endl;
return 0;
}
You can rewrite the Rand() function like this:
double Rand()
{
static random_device seeder;
static mt19937 eng(seeder());
uniform_real_distribution<double> dist(0, 1);
return dist(eng);
}
Here's a demo.
There are several problems with the code.
First, it decides if it should use std::random_device based on the value of .entropy().
I'm not sure if it correctly detects the broken random_device of pre-GCC-9.2 MinGW (which returns the same sequence of numbers every time you run the program), and I don't have an old MinGW on my hands to check that. But in any case, according to cppreference, it will incorrectly decide to avoid random_device on libc++, where .entropy() always returns 0.
My suggestion would be to use std::random_device unconditionally. If you have an old MinGW where it's broken, update the compiler.
The second problem is that it recreates mt19937 eng each time the function is called, which doesn't make much sense. It should probably be static. If the code uses time-based seeding (.entropy() happens to return 0), then it might give you the same number because the function is called several times without delay; otherwise it's just inefficient.
Here's the fixed code:
#include <iostream>
#include <random>
double Rand()
{
static std::mt19937 eng(std::random_device{}());
std::uniform_real_distribution<double> dist(0, 1);
return dist(eng);
}
int main()
{
for (int i = 0; i < 10; ++i)
std::cout << Rand() << std::endl;
}
I've also removed the std::bind call, which was completely unnecessary, and the std::srand call, which didn't do anything because you don't use std::rand.
If this program gives you the same numbers every time you run it, it probably means that you have an old MinGW where random_device is broken. Then update the compiler. (MSYS2 is a good way to get a bleeding-edge GCC on Windows.)

random numbers within a function c++

I am trying to better use and understand functions and in this case I need to figure out how to make this function in particular return 2 different random numbers.I have set up the ctime and can successfully call my function and make my variable(message) equal the random number but when I call it again and ask it to print out the newest random number they are both the same.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int RandomNumberGen (int x);
int main()
{
srand(unsigned(time(0)));
int Ran;
int message;
message = RandomNumberGen (Ran);
cout << "Number 1 " << message << endl;
message = RandomNumberGen (Ran);
cout << "Number 2 " << message << endl;
return 0;
}
int RandomNumberGen (int Ran)
{
unsigned int RandomNum = 0;
RandomNum = rand()%8 + 4;
return RandomNum;
}
As you can see I set the function to output a random number and write it on screen and then I call the same function again and write that one on screen(write the second # on screen).Yet every time I call the function both numbers are written on the screen as the same even though I am generating a random number each time.
I know this is a simple and easy task but please let me know if what I am attempting to do is possible or do I need another separate function for the 2nd number.
My end goal is to base a lot of events and things off of one random number function so I can essentially call the function for a random number and then let it determine what happens next.
I placed in the code as you asked.I hope this is what you meant.I appreciate all the help and am very grateful for the answers.I plan to be using this more so I will be sure to get it right for you guys!
You called srand in the function RandomNumberGen, which is called multiple times. That's wrong, srand should be called only once, try put it in main instead.
Or better, instead of the C library crandom functions, use the methods in random if that's available.
Take a look at this question and particularly the answer. It should clarify some things about srand() and rand()
I quote the answer:
Seed is usually taken from the current time, which are the seconds, as in time(NULL), so if you always set the seed before taking the random number, you will get the same number as long as you call the srand/rand combo multiple times in the same second.
Basically what you should do, is call srand() only once at the beginning of your application and not in the function. Because your function will be called twice at a very short interval. Almost all the time in the same second. Generating the same starting sequence for the rand() function
you shouldn't seed the random number generator with each call, but only once. your two calls to the function probably execute so fast that the value of time(null) is still the same, and the same seed will produce the same pseudo random sequence.
(btw., you should use null or NULL, not 0 for a null pointer, and you do not use the parameter you pass to your randomnumbergen function, so you could just remove it entirely.)

Using <random> in C++

Thanks in advance for reading. I am completely new to C++ (though not programming in general) and don't really understand much. The problems I am working on requires a large quantity of high-quality random numbers, and the default rand() function isn't sufficient. I tried using the "random" library but couldn't get it to work. The following simple code:
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <random>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
mt19937 gen(random_device());
normal_distribution<double> randn(0.0, 1.0);
double t;
for (int i = 0; i < 50; i++){
t = randn(gen); //program compiles correctly if call to randn is omitted
cout << t << "\n";
}
int a;
cin >> a;
}
Fails to compile, giving me 10 errors, most along the lines of:
error C2780: '_Rty std::_Nrand(_Engine &,float,_Rty)' : expects 3 arguments - 2 provided
I tried other generators and probability distributions - same problem. Any ideas?
mt19937 gen(random_device());
This is an example of the so-called most vexing parse. The compiler actually parses this as a declaration of a function called gen which takes an argument of type random_device() (i.e., function taking zero arguments and returning std::random_device) and returning std::mt19937. So first you would have to change it to:
mt19937 gen(random_device{}); // new C++11 uniform initialization syntax
But this is still wrong, because the argument to the constructor of std::mt19937 is supposed to be a seed value. random_device{} is an object which produces a seed value when you invoke its operator(). So the actual correct declaration is:
mt19937 gen(random_device{}());
You are creating the generator incorrectly. You should be creating a std::random_device object and then calling it like a function and passing the result to the std::mt19937 constructor:
random_device rd;
mt19937 gen(rd());
Your current code is demonstrating what is known as the "most vexing parse" in C++. Specifically, the following is a function declaration:
mt19937 gen(random_device());
It declares a function called gen that returns a mt19937 and takes a single argument which is a function returning random_device and taking no arguments. If you had corrected this to be a variable definition, you would have received an error saying that you were passing the wrong type argument to the mt19937 constructor.
This:
mt19937 gen(random_device());
has two problems.
Firstly, this is the so-called "most vexing parse", and is interpreted as a function declaration (a function called gen which takes a pointer to a function returning random_device as its parameter).
Secondly, random_device is a type, so random_device() is an object of that type. To get a random number out of that, you want random_device()().
The following should fix both problems:
random_device dev;
mt19937 gen(dev());
or, if you want the device to be temporary,
auto seed = random_device()();
mt19937 gen(seed);