Whenever I run the following program the returned values are always 6 or 13.
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
//void randomLegs();
//void randomPush();
//void randomPull();
//void randomMisc();
int main(int argc, const char * argv[])
{
srand(time(NULL));
//randomLegs();
cout << rand() % 14;
return 0;
}
I have run the program close to a hundred times during today and yesterday.
Can anyone tell me what I'm doing wrong?
Thank you.
EDIT: By the way, if I change the range of rand() to say 13 or 15 it works just fine.
Per wikipedia, the multiplier being used in Apple's MCG random number generator is 16807. This is divisible by 7, so the first random number produced after srand() will have only one bit of entropy mod 14 (that is, it can only take on two values).
It's a crappy RNG they've got there. An easy solution, though, is just to call rand() a few times right after srand, and discard the results.
I can reproduce the problem on Mac OS X 10.9 with Xcode 5 - it looks like it might actually be a bug, or at least a limitation with rand()/srand() on OS X 10.9.
I recommend you use arc4random() instead, which works a lot better than rand(), and which doesn't require that you randomize the seed:
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, const char * argv[])
{
cout << (arc4random() % 14) << endl;
return 0;
}
Test:
$ g++ -Wall -O3 srand.cpp && ./a.out
5
$ ./a.out
8
$ ./a.out
0
$ ./a.out
8
$ ./a.out
11
$ ./a.out
8
$ ./a.out
3
$ ./a.out
13
$ ./a.out
9
$
rand() % 14 is often a poor random number generator. You'll probably get better results with this
(int)(14*(rand()/(RAND_MAX + 1.0)))
Related
I applied the random number generator to my code although the first number generated doesn't change when I run the code second or the third time. The other numbers change however and the issue is only on the first value. I'm using code blocks; Cygwin GCC compiler (c++ 17). Seeding using time.
#include <iostream>
#include <random>
#include <ctime>
int main()
{
std::default_random_engine randomGenerator(time(0));
std::uniform_int_distribution randomNumber(1, 20);
int a, b, c;
a = randomNumber(randomGenerator);
b = randomNumber(randomGenerator);
c = randomNumber(randomGenerator);
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
std::cout<<c<<std::endl;
return 0;
}
In such a case when I run the code the first time it may produce a result like a = 4, b = 5, c = 9. The second and further time (a) remains 4 but (b) and (c) keep changing.
Per my comment, the std::mt19937 is the main PRNG you should consider. It's the best one provided in <random>. You should also seed it better. Here I use std::random_device.
Some people will moan about how std::random_device falls back to a deterministic seed when a source of true random data can't be found, but that's pretty rare outside of low-level embedded stuff.
#include <iostream>
#include <random>
int main() {
std::mt19937 randomGenerator(std::random_device{}());
std::uniform_int_distribution randomNumber(1, 20);
for (int i = 0; i < 3; ++i) {
std::cout << randomNumber(randomGenerator) << ' ';
}
std::cout << '\n';
return 0;
}
Output:
~/tmp
❯ ./a.out
8 2 16
~/tmp
❯ ./a.out
7 12 14
~/tmp
❯ ./a.out
8 12 4
~/tmp
❯ ./a.out
18 8 7
Here we see four runs that are pretty distinct. Because your range is small, you'll see patterns pop up every now and again. There are other areas of improvement, notably providing a more robust seed to the PRNG, but for a toy program, this suffices.
I am trying to perform some operations on a text file containing a repetition of a C based string and some numbers. My code successfully carried out the operation on the first set but it would not get to the remaining sets.
Please see the content of the text file below:
Max Scherzer 2017
6.2 4 2 2 2 7
6.0 4 3 1 2 10
mod Cameron 2018
6.4 4 1 2 1 3
6.0 4 3 5 2 8
John Brandonso 2019
6.1 1 3 5 2 7
6.5 4 7 3 4 10
I have used .eof() and it completely messed up what i am doing.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
char playername [25];
int season;
ifstream gamefilein;
gamefilein.open("C:\\Users\\troy\\Desktop\\GAME_SCORE\\gameinfo.txt");
if(!gamefilein)
{
cout<<"unable to open file";
}
double IP;
int H,R,ER,BB,K;
int counter=0;
double totalscore=0;
while(!gamefilein.fail())
{
gamefilein.get(playername,25);
gamefilein>>season;
cout<<playername<<season<<endl;
cout<<"Game Scores:"<<endl;
while(gamefilein>>IP>>H>>R>>ER>>BB>>K)
{
int IPa=IP;
int IPb=(IP-IPa)*10;
int IPc=0;
if(IPa>4)
{
IPc=IPa-4;
}
int score=50+(IPa*3)+(IPb*1)+(IPc*2)+(K*1)-(H*2)-(ER*4)-((R-ER)*2)-(BB*1);
cout<<score<<endl;
counter++;
totalscore+=score;
}
cout<<"Number of Games Started: "<<counter<<endl;
cout<<fixed<<setprecision(2)<<"Average Game Score:
<<(totalscore/counter)<<endl<<endl;
}
gamefilein.close();
return 0;
}
I get the below result, but I want the same result for the rest of the information in the text file, for example, I am expecting two more results like the one I have below.
Max Scherzer 2017
Game Scores:
63
64
Number of Games Started: 2
Average Game Score: 63.50
Aren't you reading the file as a char array?
If I read this correctly you try to shift an int and double over a char array with numbers in a STRING right?
e.g. "6.2" string is different than a 6.2 double number in your memory, hence why it cant work.
You also seem to have a lot of spaces which should not forget as well.
Where do you get that string to begin with? I would recommend you change the creation of that file to a more convenient format e.g. cv or json
I just solved my problem myself. The problem occurred when the loop operating on the integers and double completes its run and sees the character-based string that is in the next dataset. So i inserted a clear member function just at the point where i check for end of file
(gamefilein.clear())
and that solved my problem.
Thanks for attempting to help
i had the following problem in my book:
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
clrscr();
randomize();
int Game[]={10,16},P;
int Turn=random(2)+5;
for(int T=0;T<20;T++)
{
P=random(2);
cout<<Game[P]+Turn<<"#";
}
getch();
}
The output comes like 16#22#16#16#16#22#....20 times...
Why the output of this always comes either 16# or 22#?? why not 15# or 21#?? i would like to the mechanism of this program. Thanks.
turn=random(2)+5;
if random(2) gives 0 then turn becomes turn=0+5=5 which implies that i should get 10+5=15 and 16+5=21 along with 16 and 22 but i m not getting them.
We got the above question in our computer science theory exam and we were to chose the correct answer(i.e it generates 16 and 22) but how will i am going to know that it will generate only 16 and 22. As i explained above 15 and 21 are also possible..
maybe this helps:
The seed for the random number generator is not set.
If you call srand(time(NULL)) then you will get more random results
C++ rand() gives same number when running process
You need to give a seed value that would help get "really" random. mumbers
A computer cannot randomize numbers by itself, it uses a seed for that.
But seed's aren't completely random they just have a specific order, like:
1
2
8
5
4
These numbers look pretty random but when you run the program the next time you will get:
1
2
8
5
4
The exact same.
To prevent this we use the time as a seed, time always changes so it will always generate new numbers.
#include <time.h>
srand(time(NULL)); // srand is the function to randomize numbers from a seed, we use 'time' as seed here
this video explains it.
Because Turn is only randomized once - at the beginning of the loop. If you move the assignment of Turn into your loop, you should get 15 and 21 also:
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
clrscr();
randomize();
int Game[]={10,16},P;
int Turn;
for(int T=0;T<20;T++)
{
P=random(2);
Turn=random(2)+5;
cout<<Game[P]+Turn<<"#";
}
getch();
}
Also, as said by others, if you want the output to differ between runs, you will need to seed your random number generator, for instance by calling srand() with a seed. For instance:
#include <time.h>
(...)
srand(time(NULL));
Okay, I'm done banging my head against my desk. I'm trying to compute huge powers of 2 [beyond what's capable of being held in the uint64_t data type] by holding digits in a vector of 'char's. Here is my program, followed by my actual outputs:
/*
This program doubles a very large number by using a vector of char types
Usage: program.exe [number]
Output will be 2^[number]
*/
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[])
{
vector<char> BigNum;
BigNum.push_back('2');
int carry=0, digit;
int power=atoi(argv[1]);
power-=1;
for(int x=0;x<power;x++) //Example: going from 16 to 32. x==4
{
for(int y=BigNum.size()-1;y>=0;y--) //Go from BigNum[1] to BigNum[0] ('6' then '1')
{
digit=atoi(&BigNum[y]); //digit = 6, then digit=1
BigNum[y]=(char)(((digit*2+carry)%10)+48); //BigNum[1]=(char)(6*2+0)%10+48 = '2' in char
//BigNum[0]=(char)(1*2+1)%10+48 = '3' in char
carry=digit*2/10; //carry=1, then 0
}
if(carry==1) //does not execute. BigNum=={'3','2'}
{
BigNum.push_back('0');
for(int y=BigNum.size()-1;y>0;y--)
{
BigNum[y]=BigNum[y-1];
}
BigNum[0]='1';
carry=0;
}
}
for(int x=0;x<BigNum.size();x++) cout<<BigNum[x];
}
Compiled with:
g++ program.cpp -o program
So here are my results when I run the program:
C:\MyApps\program 2
4
C:\MyApps\program 3
8
C:\MyApps\program 4
16
Okay, looks good so far... even my "if(carry==1)" section, where I push a number to the FRONT of the vector works, since we "carried the 1" to get into double digits. Let's continue:
C:\MyApps\program 5
52
What?
C:\MyApps\program 6
26
What what?
C:\MyApps\program 654
84
C:\MyApps\program 654444
00
It never gets to triple digits... and what the heck is going on?
You're applying atoi to something that isn't a null-terminated string. In practice, it may well look in memory like a null-terminated string, but not the one you actually want it to look like.
The cleanest way to fix this is probably to store actual digit values 0..9 rather than ASCII '0'..'9' in your vector. You'll find that the code is nicer that way too.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm trying to generate a random int that is either 0 or 1 in C++. Right now, I receive a 0 every time I run this code, and I'm not sure why. What's the problem here?
#include <ctime>
#include <cstdlib>
srand(time(0));
int randomval = rand() % 2;
cout << randomval << endl;
It is called bad luck. Try it again.
I know this is an older question but I believe this answers the question properly.
Don't re-seed the the generator every time you run that code.
By seeding it to the same value every time, you're just gonna get the same "random" number. Remember this is a Pseudo-Random number generator, so based on the seed value, a "random" number will be generated. So if you seed it with the same number every time you're just gonna get the same number every time.
The solution is to call srand(time(NULL)) only once in your program execution. Then, each call to rand() will give you a different number every time.
On theory, there's 50% chance you get 0, and 50 - 1. You may want to try with different modulo - for example 100, to check if this works. And I'm sure it does.
You have just ran this code a few times, not enough.
Other idea to test it:
srand(time(0));
for( int i = 0; i < 1000000; ++i )
{
assert( 0 == ( rand() % 2 ) );
}
I would like to add that when you use srand(time(0)); the "random number" will always be the same in the same second. When I tried to run your program 10000 times and group it by uniq I saw that the number would not change within a second.
for i in `seq 1 10000`; do ./a.out; done | uniq -c
693 0
3415 1
675 0
673 1
665 0
674 1
668 0
711 1
694 0
673 1
459 0
bool random() {
if (rand() % 2 == 0)
return true;
else return false;
}
Call srand(time(NULL)); just once.
Then use a loop like this, you will always get a 0 or 1 this way.
#include <stdio.h>
#include <stdlib.h>
srand(time(NULL));
for (i=0;i<10;i++)
{
printf("%d\n",rand() % 2);
i++;
}
return 0;
Although your code suggests that you want to receive them equally likely, you didn't state that, and perhaps you have simply thought that it was impossible to do otherwise. If you want a different distribution, and you are willing to rewrite your code (and make it C++11 compliant), you can do the following:
const double chance = 0.3; // this is the chance of getting true, between 0 and 1;
std::random_device rd;
std::mt19937 mt(rd());
std::bernoulli_distribution dist(chance);
bool result = dist(mt);
If you will need to do that in a loop, only repeat the last statement dist(mt), keep all the generated objects as they are without recreating them.
You are not checking against anything. Use:
#include <ctime>
#include <cstdlib>
srand(time(0));
int randomval = rand() % 2 == 0;
cout << randomval << endl;