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++.
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;
}
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;
}
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
Hi
It is possible to generate random number within a range (-x,x) using rand()?? If not, how can I generate random number withing that range ?
// return a random number between 0 and limit inclusive.
int rand_lim(int limit) {
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
// Return a random number between lower and upper inclusive.
int rand_lim(int lower, int upper) {
int range = abs(upper-lower);
return rand_lim(range) + lower;
}
As usual, all the others I've seen in this thread can/will produce at least slightly skewed results.
I am just a simple Basic programmer, but I feel like I am missing the point. The answer seems simple. Please pardon the VB code
Dim prng As New Random
Const numEach As Integer = 100000
Const x As Integer = 3 'generate random number within a range (-x,x) inclusive
Dim lngth As Integer = Math.Abs(-x - x) + 1
Dim foo(lngth - 1) As Integer 'accumualte hits here
For z As Integer = 1 To (numEach * lngth)
Dim n As Integer = prng.Next(lngth) 'generate number in inclusive range
foo(n) += 1 'count it
'n = x - n 'actual n
Next
Debug.WriteLine("Results")
For z As Integer = 0 To foo.Length - 1
Debug.WriteLine((z - x).ToString & " " & foo(z).ToString & " " & (foo(z) / numEach).ToString("n3"))
Next
Debug.WriteLine("")
Typical results
Results
-3 99481 0.995
-2 100214 1.002
-1 100013 1.000
0 100361 1.004
1 99949 0.999
2 99755 0.998
3 100227 1.002
Results
-3 100153 1.002
-2 99917 0.999
-1 99487 0.995
0 100383 1.004
1 100177 1.002
2 99808 0.998
3 100075 1.001
Check out the answers to this question.
I need random numbers from 1 to 9 (without 0).
//numbers 0 to 9
int iRand = rand() % 10;
But I need 1 to 9.
Thanks.
Just this:
int iRand = (rand() % 9) + 1;
Well, you know how to get a random integer in the range [0, x], right? That's:
rand() % (x + 1)
In your case, you've set x to 9, giving you rand() % 10. So how can you manipulate a range to get to 1-9? Well, since 0 is the minimum value coming out of this random number generator scheme, we know we'll need to add one to have a minimum of one:
rand() % (x + 1) + 1
Now you get the range [1, x + 1]. If that's suppose to be [1, 9], then x must be 8, giving:
rand() % 9 + 1
That's how you should think about these things.
Try:
int iRand = 1 + rand() % 9;
It works by taking a random number from 0 to 8, then adding one to it (though I wrote those operations in the opposite order in the code -- which you do first comes down to personal preference).
Note that % has higher precedence than +, so parentheses aren't necessary (but may improve readability).
To initialize the random number generator call srand(time(0)); Then, to set the integer x to a value between low (inclusive) and high (exclusive):
int x = int(floor(rand() / (RAND_MAX + 1.0) * (high-low) + low));
The floor() is not necessary if high and low are both non-negative.
Using modulus (%) for random numbers is not advisable, as you don't tend to get much variation in the low-order bits so you'll find a very weak distribution.
How about
int iRand = (rand() % 9) + 1;
doh beaten by seconds
Regardless that the answer is picked, modulo based ranging is biased. You can find that all over the internet. So if you really care about that then you have to do a bit more than that (assume arc4random() return a 4 byte integer):
#define NUMBER 9.0
#define RANDOM() (((int)(arc4random() / (float)0xffffffff * (float)NUMBER) + 1) % (NUMBER + 1))
I leave it to you to figure out the correct syntax since you sound like a quite capable developer.