rand() function in c++ - 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.).

Related

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

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.

Required: large number (max 1000 digits) stored in string modulo 11

I have a question, which is to find the modulo 11 of a large number. The number is stored in a string whose maximum length is 1000. I want to code it in c++. How should i go about it?
I tried doing it with long long int, but its impossible that it can handle the corner case value.
A number written in decimal positional system as a_na_{n-1}...a_0 is the number
a_n*10^n+a_{n-1}*10^{n-1}+...+a_0
Note first that this number and the number
a_0-a_{1}+a_{2}+...+(-1)^{n}a_n
which is the sum of its digits with alternating signs have the same remainder after division by 11. You can check that by subtracting both numbers and noting that the result is a multiple of 11.
Based on this, if you are given a string consisting of the decimal representation of a number, then you can compute the remainder modulo 11 like this:
int remainder11(const std::string& s) {
int result{0};
bool even{true};
for (int i = s.length() - 1; i > -1; --i) {
result += (even ? 1 : -1) * ((int)(s[i] - '0'));
even = !even;
}
return ((result % 11) + 11) % 11;
}
Ok, here is the magic (math) trick.
First imagine you have a decimal number that consists only of 1s.
Say 111111, for example. It is obvious that 111111 % 11 is 0. (Since you can always write it as the sum of a series of 11*10^n). This can be generalized to all integers consists purely of even numbers of ones. (e.g. 11, 1111, 11111111). For those with odd number of ones, just subtract one from it and you will get a 10 times some number that consists of odd numbers of one (e.g 111=1+11*10), so their modulo to 11 would be 1.
A decimal number can be always written as the form of
where a0 is the least significant digit and an is the most significant digit. Note that 10^n can be written as 10^n - 1 + 1, and 10^n - 1 is a number consists of n nines. If n is even, then you will get 9 times some even number of ones, and its modulo to 11 is always 0. If n is odd, then we get 9 times some odd number of ones, and its modulo to 11 is always 9. And don't forget we've still got a +1 after 10^n - 1 + 1 so we need to add a to the result.
We are very close to our results now: we just have to add things up and do a final modulo to 11. The pseudo-code would be like:
Initialize sum to 0.
Initialize index to 0.
For every digit d from the least to most significant:
If the index is even, sum += d
Otherwise, sum += 10 * d
++index
sum %= 11
Return sum % 11

Random Number Generator with Modulo

I tried a small experiment with C++ random number generator code. I will post the code for everyone to see.
unsigned int array[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int rand_seed = 4567;
int loop = 0;
srandom(rand_seed);
while (loop < 2147483647)
{
array[random() % 10]++;
loop++;
}
for (int i = 0; i < 10; i++)
{
cout << array[i] << endl;
}
It's a simple code, not much to explain here. I learned that modulo operation causes a small bais, in this case the occurrence of 0 should be higher than other values since, 0 itself is counted and whenever 10 occurs. But when I display the contents of my array, the values are almost the same for all number between 0 and 9 (inclusive).
Can anyone let me know that this bias thing actually is correct or not? If yes that modulo operation does introduce bias, why can't I see it?
In math terms, can I say that my random variable X can have definite values between 0 and 9 (inclusive) and by ploting the frequency values (essentially array values), the resultant graph is a probability density function.
Just to make the question complete here is the result what I get in my array.
214765115
214745521
214749449
214749304
214747088
214733986
214745858
214743477
214760340
214743509
The bias will be larger as the value of the modulo is increased, and smaller as the maximum random number is increase. In this case 10 is very small compared to the largest random number, so the bias will be almost immeasurable.
If you want to see a better example, use fewer of the bits returned for your random numbers.
int random_value = random() & 0xfff;
array[random_value % 10]++;
It's a simple code, not much to explain here. I learned that modulo
operation causes a small bais, in this case the occurrence of 0 should
be higher than other values since, 0 itself is counted and whenever 10
occurs.
not only 10, but every other number will wrap to something between [0,9] too, because modulo is done with 10 as divisor. So there is a mapping here from values returned by random() (i.e. let's assume [0,255], POSIX random() has wider range but the idea is important) to domain [0,9]. This introduces bias.
In math terms, can I say that my random variable X can have definite
values between 0 and 9 (inclusive) and by ploting the frequency values
(essentially array values), the resultant graph is a probability
density function.
Definitely this is a distribution, however this is not uniform on range [0,9] but skewed to the left. In our example there are n=256 possibilities, and here is a probability density function
x f(x)
0 26/256
1 26/256
2 26/256
3 26/256
4 26/256
5 26/256
6 25/256
7 25/256
8 25/256
9 25/256
sum 1
For the example, suppose that random returns a unsigned char so value between [0; 255]
Now if we use modulo % 10, we will have a little more 0, 1, 2, 3, 4, 5 because of [250; 255].

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

C++ random number 1-9

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.