Karolis
Karolis

Reputation: 137

C++ generating random numbers inside loop

I want to generate random numbers inside loop but results are always same numbers.
What I'm doing wrong? Thanks.

Code

#include <fstream>
#include <ctime>
#include <cstdlib>

using namespace std;

const char duom[] = "U1.txt";
const char rez[] = "U1_rez.txt";

void num_gen(int & x, int & y);

int main(){
    srand(time(NULL));

    int x, y;

    ifstream fd(duom);
    fd >> x >> y;
    fd.close();

    ofstream fr(rez);
    for(int j = 1; j <= 4; j++){
        num_gen(x, y);
        fr << x << " + " << y << " = "<< x + y << endl;
        fr << x << " - " << y << " = "<< x - y << endl;
        fr << x << " * " << y << " = "<< x * y << endl;
        fr << x << " / " << y << " = "<< x / y << endl;
        fr << "************" << endl;
    }
    fr.close();
    return 0;
}

void num_gen(int & x, int & y){
     x = 3 + (rand() % 10);
     y = 3 + (rand() % 10);
}

Result

4 + 8= 12
4 - 8= -4
4 * 8= 32
4 / 8= 0
************
4 + 9= 13
4 - 9= -5
4 * 9= 36
4 / 9= 0
************
9 + 11= 20
9 - 11= -2
9 * 11= 99
9 / 11= 0
************
12 + 8= 20
12 - 8= 4
12 * 8= 96
12 / 8= 1
************

Upvotes: 3

Views: 3480

Answers (3)

MacGruber
MacGruber

Reputation: 162

Might be because the the random method is running with time of the computer. So if in the same 1/10000 of a second you computer do all process he need to do, you might read the same number since the random method haven't refresh the value. Try to put a sleep at the end of the for (like sleep(100)) and check if the values changed.

Upvotes: 2

Anwesha
Anwesha

Reputation: 736

With the advent of C++11/14 you should actually give up using srand & rand & use the more efficient RANDOM NUMBER GENERATING MACHINES declared in the header #include<random>. Illustrating in a simple example :-

#include <iostream>
#include <random>   // for default_random_engine & uniform_int_distribution<int>
#include <chrono>   // to provide seed to the default_random_engine
using namespace std;

default_random_engine dre (chrono::steady_clock::now().time_since_epoch().count());     // provide seed
int random (int lim)
{
    uniform_int_distribution<int> uid {0,lim};   // help dre to generate nos from 0 to lim (lim included);
    return uid(dre);    // pass dre as an argument to uid to generate the random no
}

int main()
{
    for (int i=0;i<10;++i)
    cout<<random(10)<<" ";
    return 0;
}

One of the outputs of the above code is :-

8 5 0 4 2 7 9 6 10 8

See, the numbers vary from 0 to 10. Give your limits in uniform_int_distribution according to your desired output. This thing seldom fails & you can generate random numbers in greater ranges without worrying about outrageous outputs like you had.

Upvotes: 4

lrleon
lrleon

Reputation: 2648

I think your code should generate different "pseudo" random numbers between 3 and 12 at each run, subject to that more of one second has elapsed between each run. Check if all this is really what you want.

Maybe you just run it much faster than the increase in a second when you call to time(NULL), which return the number of seconds since the epoch.

Anyway, your random numbers are not very good because you use the lower order bits. I transcript this excerpt from the rand() man page:

In  Numerical Recipes in C: The Art of Scientific Computing (William H.
       Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New
       York:  Cambridge University Press, 1992 (2nd ed., p. 277)), the follow-
       ing comments are made:
              "If you want to generate a random integer between 1 and 10,  you
              should always do it by using high-order bits, as in

                     j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

              and never by anything resembling

                     j = 1 + (rand() % 10);

              (which uses lower-order bits)."

Upvotes: 1

Related Questions