My output is 20 random 1\'s, not between 10 and 1, can anyone explain why this is happening?
#include
#include
#include <
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
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.
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.
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).
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)))
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