why does my random number generator always start with a '1'? - c++

int number_generator(bool new_id)
{
if (new_id)
{
srand(time(NULL));
int x = 99999 + (rand() % 999999);
return x;
}
else
{
throw std::runtime_error("Oops! something went wrong");
}
}
This function generates a random 6 digit number given a true argument. I have compiled it many times, and the number it generates always start with a '1'. What am I doing wrong?

rand() returns a number between 0 and RAND_MAX. The latter can be as low as 32767. C++ only requires RAND_MAX to be at least this large. A C++ implementation could use a larger value, but that is not mandated by the standard.
It is possible (even likely) that your implementation chose the minimum admissible value for RAND_MAX, i.e. 32767. If that is the case, your computed value 99999 + (rand() % 999999) is equal to 99999 + rand(), hence it lies between 99999 and 99999 + 32767. This will always start with a digit 1 except for the rather unlikely case where rand() is zero, causing the result to be 99999.

std::rand returns a pseudo-random integral value between ​0​ and RAND_MAX. That number modulo 999999
rand() % 999999
rand() has to return a number in range [100001, 999998] to have a 2 as starting digit. There is no guarantee rand() will return something in this interval, check RAND_MAX on your system.

Related

Why is rand() giving me negative numbers?

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;
}

Trying to take 1 random digit at a time

I am new to cpp programing, and new to stackoverflow.
I have a simple situation and a problem that is taking more time than reasonable to solve, so I thought I'd ask it here.
I want to take one digit from a rand() at a time. I have managed to strip of the digit, but I can't convert it to an int which I need because it's used as an array index.
Can anyone help? I'd be appreciative.
Also if anyone has a good solution to get evenly-distributed-in-base-10 random numbers, I'd like that too... of course with a rand max that isn't all 9s we don't have that.
KTM
Well you can use the modulus operator to get the digit of what number rand returns.
int digit = rand()%10;
As for your first question, if you have a character digit you can subtract the value of '0' to get the digit.
int digit = char_digit - '0';
If one wants a pedantic even distribution of 0 to 9 one could
Assume rand() itself is evenly distributed. (Not always a good assumption.)
Call rand() again as needed.
int ran10(void) {
const static int r10max = RAND_MAX - (RAND_MAX % 10);
int r;
while ((r = rand()) >= r10max);
return r%10;
}
Example:
If RAMD_MAX was 32767, r10max would have the value of 32760. Any rand value in the range 32760 to 32767 would get tossed and a new random value would be fetched.
While not as fast as modulo-arithmetic implementations like rand() % 10, this will return evenly distributed integers and avoid perodicity in the least significant bits that occur in some pseudo-random number generators (see http://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html).
int rand_integer(int exclusive_upperbound)
{
return int((double)exclusive_upperbound*rand()/RAND_MAX);
}

Rand generating same numbers

I have a problem with the small game that I made.
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int span = 100;
srand(time(0));
int TheNumber = static_cast<double> (rand()) /RAND_MAX * (span -1) +1;
cout << "You need to guess the number between 1 and " << span << endl;
int mynumber;
int numberofAttempts = 0;
do {
cout << ++numberofAttempts <<" Attempt: ";
cin >> mynumber;
if (mynumber > TheNumber)
cout <<"Lower!" << endl;
else if (mynumber < TheNumber)
cout <<"Higher!" << endl;
} while (mynumber != TheNumber);
cout << "SUCESS!!!" << endl;
return 0;
}
The game is supposed to generate a random number between 0-100 and you are supposed to guess it. After running this code 15-20times the same numbers generated some even 8 times (the number 2 in my case).
I know that there is no absolute random number and that it uses some math formula or something to get one.I know that using srand(time(0)) makes it dependent on the current time. But how would I make it "more" random, since I don't want the stuff to happen that I mentioned above.
First time I ran it the result was 11, after running it again (after guessing the right number) , it was still 11, even though the time changed.
[ADDITION1]
If you DO truly wish to look into better random number generation, then this is a good algorithm to begin with:
http://en.wikipedia.org/wiki/Mersenne_twister
Remember though that any "Computer Generated" (i.e. mathematically generated) random number is ONLY pseudo-random. Pseudo-random means that while the outputs from the algorithm look to have normal distribution, they are truly deterministic if one knows the input seed. True random numbers are completely non-deterministic.
[ORIGINAL]
Try simply one of the following lines:
rand() % (span + 1); // This will give 0 - 100
rand() % span; // this will give 0 - 99
rand() % span + 1; // This will give 1 - 100
Instead of:
(rand()) /RAND_MAX * (span -1) +1
Also, don't cast the result of that to a double, then place into an int.
Look here also:
http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
In Response to the comment!!!
If you use:
rand() / (span + 1);
then in order to get values between 0 and 100, then the output values from rand would indeed have to be between 0 and (100 * 100), and this nature would have to be guaranteed. This is because of simple division. A value of 1 will essentially pop out when rand() produces a 101 - 201, a 2 will pop out of the division when the rand() outputs a value of 202 - 302, etc...
In this case, you may be able to get away with it at 100 * 100 is only 10000, and there are definitely integers larger than this in the 32 bit space, but in general doing a divide will not allow you to take advantage utilizing the full number space provided!!!
There are a number of problems with rand(). You've run into one of them, which is that the first several values aren't "random". If you must use rand(), it is always a good idea to discard the first four or results from rand().
srand (time(0));
rand();
rand();
rand();
rand();
Another problem with rand() is that the low order bits are notoriously non-random, even after the above hack. On some systems, the lowest order bit alternates 0,1,0,1,0,1,... It's always better to use the high order bits such as by using the quotient rather than the remainder.
Other problems: Non-randomness (most implementations of rand() fails a number of tests of randomness) and short cycle. With all these problems, the best advice is to use anything but rand().
First, rand() / RAND_MAX does not give a number between 0 and 1, it returns 0. This is because RAND_MAX fits 0 times in the result of rand(). Both are integers, so with integer division it does not return a floating point number.
Second, RAND_MAX may well be the same size as an INT. Multiplying RAND_MAX with anything will then give an overflow.

C++ generating random numbers

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

rand() function in c++

i am not quite sure how this function in c++ works:
int rand_0toN1(int n) {
return rand() % n;
}
Another tutorial on internet says to get a random number between a range you need to do something different however, with a being first number in range and n is number of terms in range:
int number = a + rand( ) % n;
I have read that it is supposed to return a random number between the value of 0 and n-1, but how does it do that? I understand that % means divide and give the remainder (so 5 % 2 would be 1) but how does that end up giving a number between 0 and n-1? Thanks for help in understanding this. I guess i don't understand what the rand() function returns.
The modulo (remainder) of division by n > 0 is always in the range [0, n); that's a basic property of modular arithmetic.
a + rand() % n does not return a number in the range [0, n) unless a=0; it returns an int in the range [a, n + a).
Note that this trick does not in general return uniformly distributed integers.
rand returns a pseudorandom value bewtween 0 and RAND_MAX, which is usually 32767.
The modulo operator is useful for "wrapping around" values:
0 % 5 == 0
1 % 5 == 1
2 % 5 == 2
3 % 5 == 3
4 % 5 == 4
5 % 5 == 0 // oh dear!
6 % 1 == 1
// etc...
As such, by combining that pseudorandom value with a modulo, you're getting a pseudorandom value that's guaranteed to be between 0 and n - 1 inclusive.
According to your own example, you seems to understand how it works.
rand() just returns an integer pseudorandom number between 0 and RAND_MAX, then you apply the modulo operator to that number. Since the modulo operator returns the remainder of division of one number by another, a number divided by N will always return a number lesser than N.
The rand() function returns an integral value in the interval
[0...RAND_MAX]. And the results of x % n will always be in the
range [0...n) (provided x >= 0, at least); this is basic math.
Please take a look here :
http://www.cplusplus.com/reference/clibrary/cstdlib/srand/
Usually you "seed" it with the time function. And then use the modulus operator to specify a range.
The c++ rand() function gives you a number from 0 to RAND_MAX (a constant defined in <cstdlib>), which is at least 32767. (from the c++ documentation)
The modulus (%) operator gives the remainder after dividing. When you use it with rand() you are using it to set an upper limit (n) on what the random number can be.
For example, lets say you wanted a number between 0 and 4. Calling rand() will give you an answer between 0 and 32767. rand() % 5, however, will force the remainder to be 0, 1, 2, 3, or 4 depending on the value rand() returned (if rand() returned 10, 10%5 = 0; if it returned 11, 11%5 = 0, etc.).