i have problem with this use of rand():
rand() / (RAND_MAX + 1.0)
I know the "simple" use for rand() (like rand() %100 + 1) but i don't understand what full sentence sentence rand() / (RAND_MAX + 1.0)
Simply speaking, rand() / (RAND_MAX + 1.0) generates a floating-point random number between 0 (inclusive) and 1.0 (exclusive). More precisely (see http://en.cppreference.com/w/cpp/numeric/random/RAND_MAX for reference), the maximal number returned can be RAND_MAX / (RAND_MAX + 1.0). However, in the context of Monte-Carlo simulations there are several important points about such random number generator because RAND_MAX is usually 32767:
The number of different random numbers that can be generated is too small: 32768. Often they run many more Monte-Carlo simulations - millions or billions - but such a limited random number generator makes pointless to run more than 32768 simulations
The generated numbers are too coarse-grained: you can get 1/32768, 2/32768, 3/32768, but never anything in between.
Limited states of random number generator engine: after generating RAND_MAX random numbers, implementations usually start to repeat the same sequence of random numbers.
Due to the above limitations of rand(), a better choice for generation of random numbers for Monte-Carlo simulations would be the following snippet (similar to the example at http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution ):
#include <iostream>
#include <random>
#include <chrono>
int main()
{
std::mt19937_64 rng;
// initialize the random number generator with time-dependent seed
uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
rng.seed(ss);
// initialize a uniform distribution between 0 and 1
std::uniform_real_distribution<double> unif(0, 1);
// ready to generate random numbers
const int nMonteCarloSimulations = 10;
for (int i = 0; i < nMonteCarloSimulations; i++)
{
double currentRandomNumber = unif(rng);
std::cout << currentRandomNumber << std::endl;
}
return 0;
}
Related
I'm trying to make it so that rand_draw holds a random positive number between 0-8. But this code keeps giving negative numbers on some iterations. What's happening?
srand(time(0));
int draw_count = 8;
int rand_draw = (2 * rand()) % draw_count;
cout << rand_draw << endl;
According to cppreference, rand():
Returns a pseudo-random integral value between 0 and RAND_MAX (0 and RAND_MAX included).
The value of RAND_MAX is implementation defined, but may very well be the maximum value that can be represented in an int. By doubling the value you get from rand(), the result may overflow into a negative number. This is actually undefined behavior.
I see no reason to double the return value of rand(). You could correct this quite simply:
int rand_draw = rand() % (draw_count + 1);
This will give you random values between 0 and 8, as you specified.
But in modern C++, using the uniform_int_distribution from the C++ Standard Library is a much better way to go. Here's the example from the linked page, modified to show the range you specified:
#include <random>
#include <iostream>
int main()
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> distrib(0, 8);
for (int n=0; n<10; ++n)
//Use `distrib` to transform the random unsigned int generated by gen into an int in [0, 8]
std::cout << distrib(gen) << ' ';
std::cout << '\n';
}
rand() function will generates a random number in this range [0, RAND_MAX).
RAND_MAX is a large number.
More details are discussed in this link
When you use 2*rand(), basically you are shifting the generated number 1 bit to the left. If the generated number is large enough that its second bit from the left side is 1, then after shifting to the left you are generating a negative number.
Here is an example:
Let's assume the generated number in hexadecimal is 0x70000011.
The four most significant bits of this number are 0111, after shifting 1 bit to left, you can see the sign bit is changing.
then you try to use the % operation which results in negative number.
rand() % draw_count -> generates number [0, draw_count)
(rand() % draw_count) + draw_count -> generates number [draw_count, 2* draw_count)
rand() % (2draw_count) -> generates number [0, 2 draw_count)
I figured out a solution, given that I can only use the rand() function. I simply added an if-statement afterwards to check if it's even, and if so keep the variable set to rand_draw, and if not, increment by 1.
int rand_draw = rand() % draw_count;
if (rand_draw % 2 == 0)
{
rand_draw = rand_draw;
}
else
{
rand_draw += 1;
}
If 5 + rand() % 6 generates a random number from 5 to 10, how would I generate a decimal number? I tried assigning a float variable to ((4 + rand() % 8) / 100), but that does not do anything except assign the variable to zero.
Personally, I'd go with something a little more robust than rand() (but that might be because I'm doing research in areas that require high-quality random numbers):
#include <random>
double randomDouble(double bottom, double top) {
std::uniform_real_distribution<double> dist(bottom, top);
std::mt19937 gen; // Mersenne Twister PRNG
return dist(gen);
}
This little function uses a Mersenne Twister, a common type of PRNG that has a period (number of random numbers before you get repetition) of 2^19937 - hence the name. Now just call it like this:
double foo = randomDouble(0.04, 0.11);
There are two basic ways to transform a number generator rand() that produces numbers in [0, RAND_MAX] range to make it produce numbers in range [a, b]:
n = rand() % (b - a + 1) + a;
n = rand() * (b - a + 1) / (RAND_MAX + 1) + a;
The second method is applicable to ranges with non-integer a and b.
Keep in mind though that aside from the already mentioned random number quality issues, this generator might not produce sufficiently dense coverage of the target range. The greater the value of RAND_MAX, the denser is the coverage.
So the following code makes 0 < r < 1
r = ((double) rand() / (RAND_MAX))
Why does having r = ((double) rand() / (RAND_MAX + 1)) make -1 < r < 0?
Shouldn't adding one to RAND_MAX make 1 < r < 2?
Edit: I was getting a warning: integer overflow in expression
on that line, so that might be the problem. I just did cout << r << endl and it definitely gives me values between -1 and 0
This is entirely implementation specific, but it appears that in the C++ environment you're working in, RAND_MAX is equal to INT_MAX.
Because of this, RAND_MAX + 1 exhibits undefined (overflow) behavior, and becomes INT_MIN. While your initial statement was dividing (random # between 0 and INT_MAX)/(INT_MAX) and generating a value 0 <= r < 1, now it's dividing (random # between 0 and INT_MAX)/(INT_MIN), generating a value -1 < r <= 0
In order to generate a random number 1 <= r < 2, you would want
r = ((double) rand() / (RAND_MAX)) + 1
rand() / double(RAND_MAX) generates a floating-point random number between 0 (inclusive) and 1 (inclusive), but it's not a good way for the following reasons (because RAND_MAX is usually 32767):
The number of different random numbers that can be generated is too small: 32768. If you need more different random numbers, you need a different way (a code example is given below)
The generated numbers are too coarse-grained: you can get 1/32768, 2/32768, 3/32768, but never anything in between.
Limited states of random number generator engine: after generating RAND_MAX random numbers, implementations usually start to repeat the same sequence of random numbers.
Due to the above limitations of rand(), a better choice for generation of random numbers between 0 (inclusive) and 1 (exclusive) would be the following snippet (similar to the example at http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution ):
#include <iostream>
#include <random>
#include <chrono>
int main()
{
std::mt19937_64 rng;
// initialize the random number generator with time-dependent seed
uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
rng.seed(ss);
// initialize a uniform distribution between 0 and 1
std::uniform_real_distribution<double> unif(0, 1);
// ready to generate random numbers
const int nSimulations = 10;
for (int i = 0; i < nSimulations; i++)
{
double currentRandomNumber = unif(rng);
std::cout << currentRandomNumber << std::endl;
}
return 0;
}
This is easy to modify to generate random numbers between 1 (inclusive) and 2 (exclusive) by replacing unif(0, 1) with unif(1, 2).
No, because RAND_MAX is typically expanded to MAX_INT. So adding one (apparently) puts it at MIN_INT (although it should be undefined behavior as I'm told), hence the reversal of sign.
To get what you want you will need to move the +1 outside the computation:
r = ((double) rand() / (RAND_MAX)) + 1;
It doesn't. It makes 0 <= r < 1, but your original is 0 <= r <= 1.
Note that this can lead to undefined behavior if RAND_MAX + 1 overflows.
This is the right way:
double randd() {
return (double)rand() / ((double)RAND_MAX + 1);
}
or
double randd() {
return (double)rand() / (RAND_MAX + 1.0);
}
My guess is that RAND_MAX is equal to INT_MAX and so you're overflowing it to a negative.
Just do this:
r = ((double) rand() / (RAND_MAX)) + 1;
Or even better, use C++11's random number generators.
this->value = rand() % (this->max + 1);
Seems to work fine between 0 and 1++.
I created a test application that generates 10k random numbers in a range from 0 to 250 000. Then I calculated MAX and min values and noticed that the MAX value is always around 32k...
Do you have any idea how to extend the possible range? I need a range with MAX value around 250 000!
This is according to the definition of rand(), see:
http://cplusplus.com/reference/clibrary/cstdlib/rand/
http://cplusplus.com/reference/clibrary/cstdlib/RAND_MAX/
If you need larger random numbers, you can use an external library (for example http://www.boost.org/doc/libs/1_49_0/doc/html/boost_random.html) or calculate large random numbers out of multiple small random numbers by yourself.
But pay attention to the distribution you want to get. If you just sum up the small random numbers, the result will not be equally distributed.
If you just scale one small random number by a constant factor, there will be gaps between the possible values.
Taking the product of random numbers also doesn't work.
A possible solution is the following:
1) Take two random numbers a,b
2) Calculate a*(RAND_MAX+1)+b
So you get equally distributed random values up to (RAND_MAX+1)^2-1
Presumably, you also want an equal distribution over this extended
range. About the only way you can effectively do this is to generate a
sequence of smaller numbers, and scale them as if you were working in a
different base. For example, for 250000, you might 4 random numbers
in the range [0,10) and one in range [0,25), along the lines:
int
random250000()
{
return randomInt(10) + 10 * randomInt(10)
+ 100 * randomInt(10) + 1000 * randomInt(10)
+ 10000 * randomInt(25);
}
For this to work, your random number generator must be good; many
implementations of rand() aren't (or at least weren't—I've not
verified the situation recently). You'll also want to eliminate the
bias you get when you map RAND_MAX + 1 different values into 10 or
25 different values. Unless RAND_MAX + 1 is an exact multiple of
10 and 25 (e.g. is an exact multiple of 50), you'll need something
like:
int
randomInt( int upperLimit )
{
int const limit = (RAND_MAX + 1) - (RAND_MAX + 1) % upperLimit;
int result = rand();
while ( result >= limit ) {
result = rand();
return result % upperLimit;
}
(Attention when doing this: there are some machines where RAND_MAX + 1
will overflow; if portability is an issue, you'll need to take
additional precautions.)
All of this, of course, supposes a good quality generator, which is far
from a given.
You can just manipulate your number bitwise by generating smaller random numbers.
For instance, if you need a 32-bit random number:
int32 x = 0;
for (int i = 0; i < 4; ++i) { // 4 == 32/8
int8 tmp = 8bit_random_number_generator();
x <<= 8*i; x |= tmp;
}
If you don't need good randomness in your numbers, you can just use rand() & 0xff for the 8-bit random number generator. Otherwise, something better will be necessary.
Are you using short ints? If so, you will see 32,767 as your max number because anything larger will overflow the short int.
Scale your numbers up by N / RAND_MAX, where N is your desired maximum. If the numbers fit, you can do something like this:
unsigned long long int r = rand() * N / RAND_MAX;
Obviously if the initial part overflows you can't do this, but with N = 250000 you should be fine. RAND_MAX is 32K on many popular platforms.
More generally, to get a random number uniformly in the interval [A, B], use:
A + rand() * (B - A) / RAND_MAX;
Of course you should probably use the proper C++-style <random> library; search this site for many similar questions explaining how to use it.
Edit: In the hope of preventing an escalation of comments, here's yet another copy/paste of the Proper C++ solution for truly uniform distribution on an interval [A, B]:
#include <random>
typedef std::mt19937 rng_type;
typedef unsigned long int int_type; // anything you like
std::uniform_int_distribution<int_type> udist(A, B);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = get_seed();
rng.seed(seedval);
int_type random_number = udist(rng);
// use random_number
}
Don't forget to seend the RNG! If you store the seed value, you can replay the same random sequence later on.
My output is 20 random 1's, not between 10 and 1, can anyone explain why this is happening?
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand((unsigned)time(0));
int random_integer;
int lowest=1, highest=10;
int range=(highest-lowest)+1;
for(int index=0; index<20; index++){
random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
cout << random_integer << endl;
}
}
output:
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Because, on your platform, RAND_MAX == INT_MAX.
The expression range*rand() can never take on a value greater than INT_MAX. If the mathematical expression is greater than INT_MAX, then integer overflow reduces it to a number between INT_MIN and INT_MAX. Dividing that by RAND_MAX will always yield zero.
Try this expression:
random_integer = lowest+int(range*(rand()/(RAND_MAX + 1.0)))
It's much easier to use the <random> library correctly than rand (assuming you're familiar enough with C++ that the syntax doesn't throw you).
#include <random>
#include <iostream>
int main() {
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
std::uniform_int_distribution<> dist(1, 10);
for(int i = 0; i < 20; ++i)
std::cout << dist(eng) << " ";
}
random_integer = (rand() % 10) + 1
That should give you a pseudo-random number between 1 & 10.
A somewhat late answer, but it should provide some additional
information if the quality of the generation is important. (Not all
applications need this—a slight bias is often not a problem.)
First, of course, the problem in the original code is the fact that
range * rand() has precedence over the following division, and is done
using integer arithmetic. Depending on RAND_MAX, this can easily
result in overflow, with implementation defined results; on all
implementations that I know, if it does result in overflow (because
RAND_MAX > INT_MAX / range, the actual results will almost certainly
be smaller than RAND_MAX + 1.0, and the division will result in a
value less than 1.0. There are several ways of avoiding this: the
simplest and most reliable is simply rand() % range + lowest.
Note that this supposes that rand() is of reasonable quality. Many
earlier implementations weren't, and I've seen at least one where
rand() % 6 + 1 to simulate a dice throw alternated odd and even. The
only correct solution here is to get a better implementation of
rand(); it has lead to people trying alternative solutions, such as
(range * (rand() / (RAND_MAX + 1.0))) + lowest. This masks the
problem, but it won't change a bad generator into a good one.
A second issue, if the quality of the generation is important, is
that when generating random integers, you're discretizing: if you're
simulating the throw of a die, for example, you have six possible
values, which you want to occur with equal probability. The random
generator will generate RAND_MAX + 1 different values, with equal
probability. If RAND_MAX + 1 is not a multiple of 6, there's no
possible way of distributing the values equaly amont the 6 desired
values. Imagine the simple case where RAND_MAX + 1 is 10. Using the
% method above, the values 1–4 are twice as likely as the the
values 5 and 6. If you use the more complicated formula 1 + int(6 *
(rand() / (RAND_MAX + 1.0))) (in the case where RAND_MAX + 1 == 10,
it turns out that 3 and 6 are only half as likely as the other values.
Mathematically, there's simply no way of distributing 10 different
values into 6 slots with an equal number of elements in each slot.
Of course, RAND_MAX will always be considerably larger than 10, and
the bias introduced will be considerably less; if the range is
significantly less than RAND_MAX, it could be acceptable. If it's
not, however, the usual procedure is something like:
int limit = (RAND_MAX + 1LL) - (RAND_MAX + 1LL) % range;
// 1LL will prevent overflow on most machines.
int result = rand();
while ( result >= limit ) {
result = rand();
}
return result % range + lowest;
(There are several ways of determining the values to throw out. This
happens to be the one I use, but I remember Andy Koenig using something
completely different—but which resulted in the same values being
thrown out in the end.)
Note that most of the time, you won't enter the loop; the worst case is
when range is (RAND_MAX + 1) / 2 + 1, in which case, you'll still
average just under one time through the loop.
Note that these comments only apply when you need a fixed number of
discrete results. For the (other) common case of generating a random
floating point number in the range of [0,1), rand() / (RAND_MAX +
1.0) is about as good as you're going to get.
Visual studio 2008 has no trouble with that program at all and happily generates a swathe of random numbers.
What I would be careful of is the /(RAND_MAX +1.0) as this will likely fall foul of integer problems and end up with a big fat zero.
Cast to double before dividing and then cast back to int afterwards
I suggest you replace rand()/(RAND_MAX + 1.0) with range*double(rand())/(RAND_MAX + 1.0)). Since my solution seems to give headaches ...
possible combinations of arguments:
range*rand() is an integer and overflows.
double(range*rand()) overflows before you convert it to double.
range*double(rand()) is not overflowing and yields expected results.
My original post had two braces but they did not change anything (results are the same).
(rand() % highest) + lowest + 1
Probably "10 * rand()" is smaller than "RAND_MAX + 1.0", so the value of your calculation is 0.
You are generating a random number (ie (range*rand()/(RAND_MAX + 1.0))) whose value is between -1 and 1 (]-1,1[) and then casting it to an integer. The integer value of such number is always 0 so you end up with the lower + 0
EDIT: added the formula to make my answer clearer
What about using a condition to check if the last number is the same as the current one? If the condition is met then generate another random number. This solution works but it will take more time though.
It is one of the simplest logics, got it from a blog. in this logic you can limit the random numbers with that given modulus(%) operator inside the for loop, its just a copy and paste from that blog, but any way check it out:
// random numbers generation in C++ using builtin functions
#include <iostream>
using namespace std;
#include <iomanip>
using std::setw;
#include <cstdlib> // contains function prototype for rand
int main()
{
// loop 20 times
for ( int counter = 1; counter <= 20; counter++ ) {
// pick random number from 1 to 6 and output it
cout << setw( 10 ) << ( 1 + rand() % 6 );
// if counter divisible by 5, begin new line of output
if ( counter % 5 == 0 )
cout << endl;
}
return 0; // indicates successful termination
} // end main
- See more at: http://www.programmingtunes.com/generation-of-random-numbers-c/#sthash.BTZoT5ot.dpuf