Hey there,
First of all, thank you very very much for your time and contributions antiRTFM. People like you are truly what make this crazy world a better place.
Onward though...
Let me first point out that I am by no means an expert C++ coder. I've been working with PHP, Python, and Ruby for a few years and I finally just decided to start tackling a compiled language. I stumbled upon your fantastic tutorials and to make a long story short, that's why I'm here.
I'd just like to alert you to a minor flaw in your original random number function(s). Take for example the following code which acts as a 'lottery,' by picking a lucky winner out of an array of ten contestants. I'm going to repeat the 'drawing' 10000 times and keep track of how many times each contestant wins. In an ideal world, using a perfect random number generator, each contestant should win roughly 1000 times each (1000 * 10 = 10000):
- Code: Select all
#include <iostream>
#include <cstdlib> //This header was missing from your example... but probably since I'm using Linux.
#include <cmath>
#include <ctime>
#include <string>
using namespace std;
int GetRand(int rangeMin, int rangeMax) {
return (int)floor(rand() / (RAND_MAX + 1.0) * (rangeMax - rangeMin) + rangeMin + 0.5 );
}
int main() {
srand((long)time(0));
string names[10] = {"John","Brad","Jose","Nick","Tom","Chris","Zach","Matt","George","Steve"};
int wins[10] = {0,0,0,0,0,0,0,0,0,0};
int i = 0;
int winner;
do {
winner = GetRand(0,9); //using your GetRand() function to pick a winner
wins[winner]++; //keep track of this win
i++;
} while (i < 10000);
i = 0;
do {
cout << names[i] << " won " << wins[i] << " times." << endl;
i++;
} while (i < 10);
return 0;
}
However, this result (or something similar) will be returned:
John won 537 times.
Brad won 1107 times.
Jose won 1116 times.
Nick won 1158 times.
Tom won 1076 times.
Chris won 1170 times.
Zach won 1125 times.
Matt won 1070 times.
George won 1085 times.
Steve won 556 times.
As you'll notice, contestants 2-9 have very similar (and expected) results, while contestants 1 and 10 have roughly 1/2 the 'wins' as everyone else. This is because the math you do inside your function dictates it. The addition of 0.5 at the end of the return statement controls this offset. The first and last contestants essentially are 'sharing' 1 contestant's wins. If that 0.5 is set to something like 0.75 or 0.25, contestant 1 and 2's wins will fluctuate accordingly.
To fix this, I was browsing the C++ library reference on the rand() function (
http://www.cplusplus.com/reference/clibrary/cstdlib/rand/) and came up with what I feel is a little better random number generator.
Here is the same situation again, only with my random number generator instead of yours:
- Code: Select all
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <string>
using namespace std;
// This is something more along the lines of what was in the reference.
int GetRand(int rangeMin, int rangeMax) {
int realMax = rangeMax + 1;
int diff = realMax - rangeMin;
return (int)(rand() % diff + rangeMin);
}
int main() {
srand((long)time(0));
string names[10] = {"John","Brad","Jose","Nick","Tom","Chris","Zach","Matt","George","Steve"};
int wins[10] = {0,0,0,0,0,0,0,0,0,0};
int i = 0;
int winner;
do {
winner = GetRand(0,9); //using my GetRand() function to pick a winner instead
wins[winner]++;
i++;
} while (i < 10000);
i = 0;
do {
cout << names[i] << " won " << wins[i] << " times." << endl;
i++;
} while (i < 10);
return 0;
}
This produces a much more expected set of results, as follows:
John won 1006 times.
Brad won 951 times.
Jose won 977 times.
Nick won 1027 times.
Tom won 1014 times.
Chris won 1020 times.
Zach won 1003 times.
Matt won 1038 times.
George won 945 times.
Steve won 1019 times.
Please don't take this as me trying to be a smart @$$ or anything, and it's very possible that I could just be missing something... but I figured I'd at least let you know so you could take a look at it.
Thank you once again for all the hard work you've put in!
cheers,
Johnny