c++ program not working in code block IDE - c++

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.)

Related

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.

Formula used for function rand() in 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.

Is it good idea to pass uninitialized variable to srand?

Is it good idea to pass uninitialized variable to srand instead of result of time(NULL)?
It is one #include and one function call less.
Example code:
#include <stdlib.h>
int main(void) {
{
usigned seed; //uninitialized
srand(seed);
}
//other code
return 0;
}
instead of
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
//other code
return 0;
}
No, it isn't.
Reading an uninitialized value results in undefined behavior. It can be zero, it can be semi-random — but as such, it can repeatedly be the same value. It may also cause compilation or runtime errors, or do any other completely unpredictable thing.
Then, someone else compiling your program will notice the compiler warning about uninitialized value and try to fix it. He may fix it correctly, or given complex enough program he may just initialize it to zero. That's how 'small' bugs turn into huge bugs.
Just try your snippet with srand() replaced by printf():
#include <stdio.h>
int main()
{
{
unsigned seed;
printf("%u\n", seed);
}
return 0;
}
On my system it repeatedly gives 0. This means that there's at least one system where your code is broken :).
No, accessing uninitialized variable is an undefined behavior. You should prefer time(NULL). Uninitialized variable method may introduce difficult to find bugs or may blow the computer.
Most of the time, effect observed would be, (on most implementation) above code would take (read) some leftover value from the stack that may be zero or something else but may be same on multiple runs defeating your purpose. time on the other hand is promising.
It's not a good idea. Undefined behaviour doesn't guarantee that you won't get the same seed on every run, which would be bad for randomness. It doesn't guarantee that your processor won't halt and catch fire either.
Another point is that uninitialized variables can result in a vulnerability. So it is not only bad design and undefined behaviour, it also can make your program exploitable.
Consider this code:
#include <stdio.h>
#include <time.h>
void print_uninitialized(void) {
unsigned var;
printf("%u\n", var);
}
void fake_init() {
unsigned var=42;
}
int main(void) {
print_uninitialized();
fake_init();
print_uninitialized();
}
Possible output:
0
42
The next example is a bit more realistic:
#include <stdio.h>
unsigned uninitialized( void ) {
unsigned var;
return var;
}
unsigned square(unsigned arg){
unsigned result=arg*arg;
return result;
}
int main( void ) {
unsigned to_square;
printf("UNINITIALIZED = %u\n", uninitialized());
while(scanf("%u", &to_square)!=EOF){
printf("%u * %u = %u\n", to_square, to_square, square(to_square));
printf("UNITNITIALIZED = %u\n", uninitialized());
}
}
The uninitialized variable can be modified by a user.
Input:
2
Output:
UNINITIALIZED = 0
2 * 2 = 4
UNITNITIALIZED = 4
In the first case there are two possibilities:
seed is a random variable (less possible)
seed is constant on every run (more possible)
time(NULL) returns the time of the system which is 99.99% different every time you run the code.
Nothing is perfect random, but using time(NULL) gives you a "more random" number then if you would use the first approach.
You should check function's usage
http://www.cplusplus.com/reference/cstdlib/srand/

Array of objects always has same random number for each item [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 8 years ago.
Improve this question
Started to try c++ again with a simple card game. I made a class for each card with two constructors, one with no values creates the card randomly and one that takes in values.
#include <string>
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <ctime>
#include <sstream>
class Card
{
private:
char suit;
int value;
public:
Card();
Card(char suit, int value);
void SetSuit(char suit);
void SetValue(int value);
...
std::string GetCard() ;
};
Card::Card(char suit, int value)
{
suit= toupper(suit);
this -> suit=suit;
this -> value=value;
}
Card::Card() //create random card
{
srand (time(0));
char suits [4] = {'D','S','H','C'};
int randNum = (rand() % 4);
SetSuit(suits[randNum]);
randNum = (rand() % 12)+2;
SetValue(randNum);
...
std::string Card::GetCard(){
...
return card.str();
}
If I create an array of card objects and then output it every card in the array has the same suit and value. I'm not sure how to get each card to be random the array.
The problem is with:
srand (time(0));
int randNum = (rand() % 4);
Probably on your system, time(0) returns the number of seconds this epoch. So when you call this code multiple times without a second elapsing, it gets the same value. Therefore you get the same random number every time.
You're supposed to do srand just once per program run. And if you need any serious sort of randomness then you need more entropy than just time(0). Even if you fix this, you could still execute your program several times and get the same card sequence every time, if all the runs begin within the same second.
The way that rand() typically works is to generate a long sequence of numbers which is predictable if you know the seed, but hard to predict just from a subset of the number. The srand function says "start the sequence at this point". If you start at the same point each time , you get the same random numbers each time. Further reading
Call srand(time(0)) only once when your application starts, e.g., at the main() function, not whenever any card is created.

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);