Even after including srand(time(NULL)) at the start of my function, (function is only called once in main) I get the same random value for r1 every time I run the program. r2 and r3 get random values fine, but I need random decimal values between 0.1 and 10.0 so what's wrong with the line containing r1?
void randNums(float &r1, float &r2, float &r3) {
srand(time(NULL));
r1 = (10 * (rand())/ (float)RAND_MAX);
r2 = 1 + (rand() % 10);
r3 = 1 + (rand() % 10);
}
I just removed the srand line and used the function to print it out a couple of times and it generated random numbers. When I was using your code to generate random numbers, it apparently displayed the same 3 random number values for r1, r2, and r3 no matter how many times I ran it. I think what Mooing Duck said was true. It might be because of overflow from 10 * rand() code.
The only downside to this is, if you were to rerun your code it will generate the same random numbers as the last session.
Related
This question already has answers here:
C++ random number same sequence every time
(2 answers)
Random seed at runtime
(3 answers)
Closed 1 year ago.
I'm using rand() in a loop to generate random numbers every time till the loop is complete, but it always gives the same number, what am I doing wrong?
bool PlayGame(int Difficulty, bool bComplete)
{
int CodeA =rand() % Difficulty + Difficulty;
int CodeB =rand() % Difficulty + Difficulty;
int CodeC =rand() % Difficulty + Difficulty;
You can use current time as seed for random generator by setting srand(time(0)); at start
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Driver program
int main(void)
{
// This program will create different sequence of
// random numbers on every program run
// Use current time as seed for random generator
srand(time(0));
for(int i = 0; i<4; i++)
printf(" %d ", rand());
return 0;
}
Output 1:
453 1432 325 89
Output 2:
8976 21234 45 8975
Output n:
563 9873 12321 24132
Ref.
If random numbers are generated with rand() without first calling srand(), your program will create the same sequence of numbers each time it runs.
The srand() function sets the starting point for producing a series of pseudo-random integers. If srand() is not called, the rand() seed is set as if srand(1)
so, set srand(time(0)); at start of the program
I am really new to C++. I am following a free online course, and one thing I had to do was to create a program which could scramble the characters of a string.
So, I created a function who received the word as parameter and returned the scrambled word. ctime and cstdlib were included and srand(time(0)); declared in the main.
Basically, the function looked like this :
std::string mixingWord(std::string baseWord)
{
std::string mixWord;
int pos(0);
for (int i = baseWord.length; i >= 0; i--)
{
if (i != 0)
{
pos = rand() % i;
mixWord += baseWord[pos];
baseWord.erase(pos,1);
}
else
{
mixWord += baseWord[0];
}
}
return mixWord;
}
And it worked just fine. But the correct solution was
std::string mixingWord(std::string baseWord)
{
std::string mixWord;
int pos(0);
while (baseWord.size() != 0)
{
pos = rand() % baseWord.size();
mixWord += baseWord[pos];
baseWord.erase(pos, 1);
}
return mixWord;
}
And it works fine as well.
My question is :
Why is the solution working ?
From what I understood, this :
rand() % value
gives out a value between 0 and the value given.
SO, since baseWord.size() returns, let's say 5 in the event of a word like HELLO. rand will generate a number between 0 and 5. So it COULD be 5. and baseWord[5] is out of bound, so it should crash once in a while, but I tried it over 9000 times (sorry, dbz reference), and it never crashed.
Am I just unlucky, or am I not understanding something ?
x % y gives the remainder of x / y. The result can never be y, because if it was, then that would mean y could go into x one more time, and the remainder would actually be zero, because y divides x evenly. So to answer your question:
Am I just unlucky, or am I not understanding something ?
You're misunderstanding something. rand() % value gives a result in the range [0,value - 1] (assuming value is positive), not [0, value].
rand() % 100 returns number between 0 and 99. This is 100 NUMBERs but includes 0 and does not include 100.
A good way to think about this is a random number (1000) % 100 = 0. If I mod a random number with the number N then there is no way to get the number N back.
Along those lines
pos = rand() % baseWord.size();
will never return pos = baseWord.size() so in your case there will not be an indexing issue
I guess you just misunderstood the modulo operator. a % b, with a and b any integer, will return values between 0 and b-1 (inclusive).
As for your HELLO example, it will only return values between 0 and 4, therefore will never encounter out of bound error.
I know that there was a program like this:
#include <iostream>
#include <string>
int main() {
const std::string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
std::string temp = "1234567890";
srand(MAGICNUMBER);
for (int i = 0;; ++i) {
for (int j = 0; j < 10; ++j)
temp[j] = alphabet[rand() % alphabet.size()];
std::cout << temp << std::endl;
}
}
Basically, random 10-symbol string generator.
I also know that the 124660967-th generated string was "2lwd9JjVnE". Is there a way to find what the MAGICNUMBER is, or, at least, the next string in the sequence?
Brute-forcing would be painful, given the time it takes to generate one such sequence, but I have some info about the compiler used (if that helps?): it was 64-bit g++ 4.8 for Linux.
UPD. Finding the next item would already be very helpful; can I do that in reasonable amount of time (especially without a seed)?
Yes, given typical rand() implementations this is likely to be possible, fairly easy, even.
rand() is typically a linear congruential generator such that each internal state of the generator is formed from a simple arithmetic equation of the previous state: x1 = (a*x0 + c) % m. You'll need to know the constants a, c and m used by the particular implementation you're targeting, and the method of producing the output value from the state (usually the values are either the entire state, or the upper half of the state). It's also important that the state is typically only 32-bits. A larger state would be more difficult.
So you need to find a state for the pRNG such that the next ten states produce the particular sequence of indices that produce the 10 characters you're looking for: 2lwd9JjVnE. So assuming the entire state is output by rand(), you need to find some 32-bit number x such that:
x % 62 = 54
(x1 = (a*x + c) % m) % 62 == 11
(x2 = (a*x1 + c) % m) % 62 == 22
(x3 = (a*x2 + c) % m) % 62 == 3
(x4 = (a*x3 + c) % m) % 62 == 61
(x5 = (a*x4 + c) % m) % 62 == 35
(x6 = (a*x5 + c) % m) % 62 == 9
(x7 = (a*x6 + c) % m) % 62 == 47
(x8 = (a*x7 + c) % m) % 62 == 13
(x9 = (a*x8 + c) % m) % 62 == 30
This could be done without too much difficulty by trying all 2^32 possible state values (assuming the typical 32-bit state). However, since the constants used were probably chosen to ensure that the RNG runs through a complete 32-bit period, you can simply choose any state at all and run it until you find this sequence.
Either way, once you know the state that produces these values, you then simply have to run the generator backwards for 124660967 * 10 steps in order to find which state was used as the original seed. To do that you'll need to compute the congruence multiplicative inverse of a mod m. Alternatively you could run it forward for (period - 124660967*10) steps.
No, it's almost not possible. As #chux pointed out in their comment the exact implementation isn't specified in the c++ standard.
You'll need to check for all of the sequences that will be generated with all possible seeds. That will run in an unreasonable amount of computing time necessary.
Though if the compiler is well known, and the implementation is open source (as is in your specific case), there could be ways to find out the initial seed value, knowing the specific rand() result for a specific iteration on the call.
If you have access to the program, disassemble it to attempt to learn what the magic number was.
Otherwise the standard doesn't specify anything about storing the srand value so you're stuck with alternate approaches, such as brute-forcing all seeds, or possibly trying to store the sequence of random numbers looking for the ten in a row that generate the string you're interested in.
I am attempting to do a Monte Carlo simulation using RANDOM_NUMBER. I am using gFortran. I want to perform the following:
Calculate monteNum (fixed number) and generate a random number, monteTest.
If monteNum >= monteTest, then generate another random number randPos which is used to select a row from an array.
Otherwise, generate a new monteTest until step 2 is satisfied.
Firstly, I tried to use a DO loop.
CALL RANDOM_SEED()
monteNum = (count_up + count_dn)/(nReal**2) ! This is just a number in [0,1].
DO i = 1, 100
CALL RANDOM_NUMBER (monteTest)
! monteTest is a randomly generated number used in Monte Carlo simulation
IF (monteNum >= monteTest) THEN
CALL RANDOM_NUMBER (randPos)
! randPos will be used to select one flippable position randomly
Vpos = INT(randPos*count)
! position of the chosen vertex; count is the length of fList
flipVertex(1,:) = fList(Vpos,:)
ELSE
i = i+1
END IF
END DO
An error arises from the ELSE statement. Since it is not known that the IF statement will produce TRUE in 100 loops, I thought a DO WHILE was a better choice.
monteTest = 0.5 ! Setting the initial value. But ideally it should be random
DO WHILE (monteNum < monteTest)
CALL RANDOM_NUMBER (monteTest)
CALL RANDOM_NUMBER (randPos)
Vpos = INT(randPos*count)
flipVertex(1,:) = fList(Vpos,:)
END DO
But it didn't work either.
The problem is that randPos is always zero for initial monteTest = 0.2 and randPos = 5.35517931E-03 for initial monteTest = 0.5. Here, the correct value of monteNum is 0.22222.
I was expecting outputs to change every time I run it, but I am getting the same output every time. Why would that be? Am I using the RANDOM_NUMBER in a wrong way?
Any help would be appreciated!
In Fortran it is forbidden to (try to) update the index variable inside a loop. So the lines
DO i = 1, 100
...
ELSE
i = i+1
END IF
won't compile.
As for your second snippet, I see no syntax errors, explain what you mean by it didn't work.
I need to get random numbers between 0 and 1.
As 0.54321, 0.8912, 0.1234342, 0.0000123 and etc
I put this code in my main and also Application constructor:
qsrand(QDateTime::currentDateTime().toTime_t());
And used this code inside one of my slots:
float prob = qrand() % 1;
I tried int, double as a return value, but it is always returning 0.
Any ideas what is going on?
Thanks
qrand() generates integer numbers between 0 to RAND_MAX and every number is perfectly divisible by 1 and giving remainder as 0. Try this instead:
float prob = (float) qrand() / (RAND_MAX+1); // 1 is exclusive