C++ How I can get random value from 1 to 12? [duplicate] - c++

This question already has answers here:
Generating a random integer from a range
(14 answers)
Closed 6 years ago.
How I can get in C++ random value from 1 to 12?
So I will have 3, or 6, or 11?

Use the following formula:
M + rand() / (RAND_MAX / (N - M + 1) + 1), M = 1, N = 12
and read up on this FAQ.
Edit: Most answers on this question do not take into account the fact that poor PRN generators (typically offered with the library function rand()) are not very random in the low order bits. Hence:
rand() % 12 + 1
is not good enough.

#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <time.h>
// initialize random seed
srand( time(NULL) );
// generate random number
int randomNumber = rand() % 12 + 1;
// output, as you seem to wan a '0'
cout << setfill ('0') << setw (2) << randomNumber;
to adress dirkgently's issue maybe something like that would be better?
// generate random number
int randomNumber = rand()>>4; // get rid of the first 4 bits
// get the value
randomNumer = randomNumer % 12 + 1;
edit after mre and dirkgently's comments

Is there some significance to the leading zero in this case? Do you intend for it to be octal, so the 12 is really 10 (in base 10)?
Getting a random number within a specified range is fairly straightforward:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
(The while loop is to prevent skewed results -- some outputs happening more often than others). Skewed results are almost inevitable when/if you use division (or its remainder) directly.
If you want to print it out so even one-digit numbers show two digits (i.e. a leading 0), you can do something like:
std::cout << std::setw(2) << std::setprecision(2) << std::setfill('0') << number;
Edit: As to why this works, and why a while loop (or something similar) is needed, consider a really limited version of a generator that only produces numbers from, say, 0 to 9. Assume further that we want numbers in the range 0 to 2. We can basically arrange the numbers in a table:
0 1 2
3 4 5
6 7 8
9
Depending on our preference we could arrange the numbers in columns instead:
0 3 6
1 4 7
2 5 8
9
Either way, however, we end up with the one of the columns having one more number than any of the others. 10 divided by 3 will always have a remainder of 1, so no matter how we divide the numbers up, we're always going to have a remainder that makes one of the outputs more common than the others.
The basic idea of the code above is pretty simple: after getting a number and figuring where in a "table" like one above that number would land, it checks whether the number we've got is the "odd" one. If it is, another iteration of the loop is executed to obtain another number.
There are other ways this could be done. For example, you could start by computing the largest multiple of the range size that's still within the range of the random number generator, and repeatedly generate numbers until you get one smaller than that, then divide the number you receive to get it to the right range. In theory this could even be marginally more efficient (it avoids dividing the random number to get it into the right range until it gets a random number that it's going to use). In reality, the vast majority of the time, the loop will only execute one iteration anyway, so it makes very little difference what we execute inside or outside the loop.

You can do this, for example:
#include <cstdlib>
#include <cstdio>
#include <time.h>
int main(int argc, char **argv)
{
srand(time(0));
printf("Random number between 1 and 12: %d", (rand() % 12) + 1);
}
The srand function will seed the random number generator with the current time (in seconds) - that's the way it's usually done, but there are also more secure solutions.
rand() % 12 will give you a number between 0 and 11 (% is the modulus operator), so we add 1 here to get to your desired range of 1 to 12.
In order to print 01 02 03 and so on instead of 1 2 3, you can format the output:
printf("Random number between 01 and 12: %02d", (rand() % 12) + 1);

(rand() % 12 + 1).ToString("D2")

Related

How does modulus and rand() work?

So, I've been nuts on this.
rand() % 6 will always produce a result between 0-5.
However when I need between, let's say 6-12.
Should I have rand() % 6 + 6
0+6 = 6.
1+6 = 7.
...
5+6 = 11. ???
So do I need to + 7 If I want the interval 6-12? But then, 0+7 =7. When will it randomize 6?
What am I missing here? Which one is the correct way to have a randomized number between 6 and 12? And why? It seems like I am missing something here.
If C++11 is an option then you should use the random header and uniform_int_distrubution. As James pointed out in the comments using rand and % has a lot of issues including a biased distribution:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::uniform_int_distribution<int> dist(6, 12);
for (int n = 0; n < 10; ++n) {
std::cout << dist(e2) << ", " ;
}
std::cout << std::endl ;
}
if you have to use rand then this should do:
rand() % 7 + 6
Update
A better method using rand would be as follows:
6 + rand() / (RAND_MAX / (12 - 6 + 1) + 1)
I obtained this from the C FAQ and it is explained How can I get random integers in a certain range? question.
Update 2
Boost is also an option:
#include <iostream>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
int main()
{
boost::random::mt19937 gen;
boost::random::uniform_int_distribution<> dist(6, 12);
for (int n = 0; n < 10; ++n) {
std::cout << dist(gen) << ", ";
}
std::cout << std::endl ;
}
You need rand() % 7 + 6.
Lowest number from rand() %7: 0.
Highest number from rand() %7: 6.
0 + 6 = 6.
6 + 6 = 12.
The modulus operation a % b computes the remainder of the division a / b. Obviously the remainder of a division must be less than b and if a is a random positive integer then a%b is a random integer in the range 0 .. (b-1)
In the comments you mention:
rand()%(max-min)+min
This algorithm produces values in the half-open range [min, max). (That is, max is outside the range, and simply denotes the boundary. Since we're talking about ranges of integers this range is equivalent to the closed range [min, max-1].)
When you write '0 - 5' or '6 - 12' those are closed ranges. To use the above equation you have to use the values that denote the equivalent half open range: [0, 6) or [6, 13).
rand() % (6-0) + 0
rand() % (13-6) + 6
Note that rand() % (max-min) + min is just a generalization of the rule you've apparently already learned: that rand() % n produces values in the range 0 - (n-1). The equivalent half-open range is [0, n), and rand() % n == rand() % (n-0) + 0.
So the lesson is: don't confuse half-open ranges for closed ranges.
A second lesson is that this shows another way in which <random> is easier to use than rand() and manually computing your own distributions. The built-in uniform_int_distribution allows you to directly state the desired, inclusive range. If you want the range 0 - 5 you say uniform_int_distibution<>(0, 5), and if you want the range 6 - 12 then you say uniform_int_distribution<>(6, 12).
#include <random>
#include <iostream>
int main() {
std::default_random_engine eng;
std::uniform_int_distribution<> dist(6, 12);
for (int i=0; i<10; ++i)
std::cout << dist(eng) << " ";
}
rand()%7+6 is more terse, but that doesn't mean it is easier to use.
There are a couple of concepts here.
First, there's the range: [ denotes inclusive. ) denotes exclusive.
The modulus operator % n produces [0,n) - 0,..n-1
When you add a value to that result, you're adding the same value to both ends of the ranges:
%n + 6 = [n,n+6)
Now, if n is 6, as it in in your case, your output will be [0,6)
%6 + 6 = [6,12)
Now what you want is [6,13)
Subtract 6 from that:
[0,7) + 6 => n%7 + 6
Second, there is the matter of using rand(). It depends on whether you really care if your data is random or not. If you do really care that it is random, I highly suggest watching Stefan T Lavalej's talk on the pitfalls of using rand() at Going Native 2013 this year. He also goes into what you should use.
If the randomness of rand() doesn't matter to you, then by all means use it.

Fastest way to find the sum of decimal digits

What is the fastest way to find the sum of decimal digits?
The following code is what I wrote but it is very very slow for range 1 to 1000000000000000000
long long sum_of_digits(long long input) {
long long total = 0;
while (input != 0) {
total += input % 10;
input /= 10;
}
return total;
}
int main ( int argc, char** argv) {
for ( long long i = 1L; i <= 1000000000000000000L; i++) {
sum_of_digits(i);
}
return 0;
}
I'm assuming what you are trying to do is along the lines of
#include <iostream>
const long long limit = 1000000000000000000LL;
int main () {
long long grand_total = 0;
for (long long ii = 1; ii <= limit; ++ii) {
grand_total += sum_of_digits(i);
}
std::cout << "Grand total = " << grand_total << "\n";
return 0;
}
This won't work for two reasons:
It will take a long long time.
It will overflow.
To deal with the overflow problem, you will either have to put a bound on your upper limit or use some bignum package. I'll leave solving that problem up to you.
To deal with the computational burden you need to get creative. If you know the upper limit is limited to powers of 10 this is fairly easy. If the upper limit can be some arbitrary number you will have to get a bit more creative.
First look at the problem of computing the sum of digits of all integers from 0 to 10n-1 (e.g., 0 to 9 (n=1), 0 to 99 (n=2), etc.) Denote the sum of digits of all integers from 10n-1 as Sn. For n=1 (0 to 9), this is just 0+1+2+3+4+5+6+7+8+9=45 (9*10/2). Thus S1=45.
For n=2 (0 to 99), you are summing 0-9 ten times and you are summing 0-9 ten times again. For n=3 (0 to 999), you are summing 0-99 ten times and you are summing 0-9 100 times. For n=4 (0 to 9999), you are summing 0-999 ten times and you are summing 0-9 1000 times. In general, Sn=10Sn-1+10n-1S1 as a recursive expression. This simplifies to Sn=(9n10n)/2.
If the upper limit is of the form 10n, the solution is the above Sn plus one more for the number 1000...000. If the upper limit is an arbitrary number you will need to get creative once again. Think along the lines that went into developing the formula for Sn.
You can break this down recursively. The sum of the digits of an 18-digit number are the sums of the first 9 digits plus the last 9 digits. Likewise the sum of the digits of a 9-bit number will be the sum of the first 4 or 5 digits plus the sum of the last 5 or 4 digits. Naturally you can special-case when the value is 0.
Reading your edit: computing that function in a loop for i between 1 and 1000000000000000000 takes a long time. This is a no brainer.
1000000000000000000 is one billion billion. Your processor will be able to do at best billions of operations per second. Even with a nonexistant 4-5 Ghz processor, and assuming best case it compiles down to an add, a mod, a div, and a compare jump, you could only do 1 billion iterations per second, meaning it will take on the order of 1 billion seconds.
You probably don't want to do it in a bruteforce way. This seems to be more of a logical thinking question.
Note - 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = N(N+1)/2 = 45.
---- Changing the answer to make it clearer after David's comment
See David's answer - I had it wrong
Quite late to the party, but anyways, here is my solution. Sorry it's in Python and not C++, but it should be relatively easy to translate. And because this is primarily an algorithm problem, I hope that's ok.
As for the overflow problem, the only thing that comes to mind is to use arrays of digits instead of actual numbers. Given this algorithm I hope it won't affect performance too much.
https://gist.github.com/frnhr/7608873
It uses these three recursions I found by looking and poking at the problem. Rather then trying to come up with some general and arcane equations, here are three examples. A general case should be easily visible from those.
relation 1
Reduces function calls with arbitrary argument to several recursive calls with more predictable arguments for use in relations 2 and 3.
foo(3456) == foo(3000)
+ foo(400) + 400 * (3)
+ foo(50) + 50 * (3 + 4)
+ foo(6) + 6 * (3 + 4 + 5)
relation 2
Reduce calls with an argument in the form L*10^M (e.g: 30, 7000, 900000) to recursive call usable for relation 3. These triangular numbers popped in quite uninvited (but welcome) :)
triangular_numbers = [0, 1, 3, 6, 10, 15, 21, 28, 36] # 0 not used
foo(3000) == 3 * foo(1000) + triangular_numbers[3 - 1] * 1000
Only useful if L > 1. It holds true for L = 1 but is trivial. In that case, go directly to relation 3.
relation 3
Recursively reduce calls with argument in format 1*10^M to a call with argument that's divided by 10.
foo(1000) == foo(100) * 10 + 44 * 100 + 100 - 9 # 44 and 9 are constants
Ultimately you only have to really calculate the sum or digits for numbers 0 to 10, and it turns out than only up to 3 of these calculations are needed. Everything else is taken care of with this recursion. I'm pretty sure it runs in O(logN) time. That's FAAST!!!!!11one
On my laptop it calculates the sum of digit sums for a given number with over 1300 digits in under 7 seconds! Your test (1000000000000000000) gets calculated in 0.000112057 seconds!
I think you cannot do better than O(N) where N is the number of digits in the given number(which is not computationally expensive)
However if I understood your question correctly (the range) you want to output the sum of digits for a range of numbers. In that case, you can increment by one when you go from number0 to number9 and then decrease by 8.
You will need to cheat - look for mathematical patterns that let you short-cut your computations.
For example, do you really need to test that input != 0 every time? Does it matter if you add 0/10 several times? Since it won't matter, consider unrolling the loop.
Can you do the calculation in a larger base, eg, base 10^2, 10^3, etcetera, that might allow you to reduce the number of digits, which you'll then have to convert back to base 10? If this works, you'll be able to implement a cache more easily.
Consider looking at compiler intrinsics that let you give hints to the compiler for branch prediction.
Given that this is C++, consider implementing this using template metaprogramming.
Given that sum_of_digits is purely functional, consider caching the results.
Now, most of those suggestions will backfire - but the point I'm making is that if you have hit the limits of what your computer can do for a given algorithm, you do need to find a different solution.
This is probably an excellent starting point if you want to investigate this in detail: http://mathworld.wolfram.com/DigitSum.html
Possibility 1:
You could make it faster by feeding the result of one iteration of the loop into the next iteration.
For example, if i == 365, the result is 14. In the next loop, i == 366 -- 1 more than the previous result. The sum is also 1 more: 3 + 6 + 6 = 15.
Problems arise when there is a carry digit. If i == 99 (ie. result = 18), the next loop's result isn't 19, it's 1. You'll need extra code to detect this case.
Possibility 2:
While thinking though the above, it occurred to me that the sequence of results from sum_of_digits when graphed would resemble a sawtooth. With some analysis of the resulting graph (which I leave as an exercise for the reader), it may be possible to identify a method to allow direct calculation of the sum result.
However, as some others have pointed out: Even with the fastest possible implementation of sum_of_digits and the most optimised loop code, you can't possibly calculate 1000000000000000000 results in any useful timeframe, and certainly not in less than one second.
Edit: It seems you want the the sum of the actual digits such that: 12345 = 1+2+3+4+5 not the count of digits, nor the sum of all numbers 1 to 12345 (inclusive);
As such the fastest you can get is:
long long sum_of_digits(long long input) {
long long total = input % 10;
while ((input /= 10) != 0)
total += input % 10;
return total;
}
Which is still going to be slow when you're running enough iterations. Your requirement of 1,000,000,000,000,000,000L iterations is One Million, Million, Million. Given 100 Million takes around 10,000ms on my computer, one can expect that it will take 100ms per 1 million records, and you want to do that another million million times. There are only 86400 seconds in a day, so at best we can compute around 86,400 Million records per day. It would take one computer
Lets suppose your method could be performed in a single float operation (somehow), suppose you are using the K computer which is currently the fastest (Rmax) supercomputer at over 10 petaflops, if you do the math that is = 10,000 Million Million floating operations per second. This means that your 1 Million, Million, Million loop will take the world's fastest non-distributed supercomputer 100 seconds to compute the sums (IF it took 1 float operation to calculate, which it can't), so you will need to wait around for quite some time for computers to become 100 so much more powerful for your solution to be runable in under one second.
What ever you're trying to do, you're either trying to do an unsolvable problem in near real-time (eg: graphics calculation related) or you misunderstand the question / task that was given you, or you are expected to perform something faster than any (non-distributed) computer system can do.
If your task is actually to sum all the digits of a range as you show and then output them, the answer is not to improve the for loop. for example:
1 = 0
10 = 46
100 = 901
1000 = 13501
10000 = 180001
100000 = 2250001
1000000 = 27000001
10000000 = 315000001
100000000 = 3600000001
From this you could work out a formula to actually compute the total sum of all digits for all numbers from 1 to N. But it's not clear what you really want, beyond a much faster computer.
No the best, but simple:
int DigitSumRange(int a, int b) {
int s = 0;
for (; a <= b; a++)
for(c : to_string(a))
s += c-48;
return s;
}
A Python function is given below, which converts the number to a string and then to a list of digits and then finds the sum of these digits.
def SumDigits(n):
ns=list(str(n))
z=[int(d) for d in ns]
return(sum(z))
In C++ one of the fastest way can be using strings.
first of all get the input from users in a string. Then add each element of string after converting it into int. It can be done using -> (str[i] - '0').
#include<iostream>
#include<string>
using namespace std;
int main()
{ string str;
cin>>str;
long long int sum=0;
for(long long int i=0;i<str.length();i++){
sum = sum + (str[i]-'0');
}
cout<<sum;
}
The formula for finding the sum of the digits of numbers between 1 to N is:
(1 + N)*(N/2)
[http://mathforum.org/library/drmath/view/57919.html][1]
There is a class written in C# which supports a number with more than the supported max-limit of long.
You can find it here. [Oyster.Math][2]
Using this class, I have generated a block of code in c#, may be its of some help to you.
using Oyster.Math;
class Program
{
private static DateTime startDate;
static void Main(string[] args)
{
startDate = DateTime.Now;
Console.WriteLine("Finding Sum of digits from {0} to {1}", 1L, 1000000000000000000L);
sum_of_digits(1000000000000000000L);
Console.WriteLine("Time Taken for the process: {0},", DateTime.Now - startDate);
Console.ReadLine();
}
private static void sum_of_digits(long input)
{
var answer = IntX.Multiply(IntX.Parse(Convert.ToString(1 + input)), IntX.Parse(Convert.ToString(input / 2)), MultiplyMode.Classic);
Console.WriteLine("Sum: {0}", answer);
}
}
Please ignore this comment if it is not relevant for your context.
[1]: https://web.archive.org/web/20171225182632/http://mathforum.org/library/drmath/view/57919.html
[2]: https://web.archive.org/web/20171223050751/http://intx.codeplex.com/
If you want to find the sum for the range say 1 to N then simply do the following
long sum = N(N+1)/2;
it is the fastest way.

Will this give me proper random numbers based on these probabilities? C++

Code:
int random = (rand() % 7 + 1)
if (random == 1) { } // num 1
else if (random == 2) { } // num 2
else if (random == 3 || random == 4) { } // num 3
else if (random == 5 || random == 6) { } // num 4
else if (random == 7) { } // num 5
Basically I want each of these numbers with each of these probabilities:
1: 1/7
2: 1/7
3: 2/7
4: 2/7
5: 1/7
Will this code give me proper results? I.e. if this is run infinite times, will I get the proper frequencies? Is there a less-lengthy way of doing this?
Not, it's actually slightly off, due to the way rand() works. In particular, rand returns values in the range [0,RAND_MAX]. Hypothetically, assume RAND_MAX were ten. Then rand() would give 0…10, and they'd be mapped (by modulus) to:
0 → 0
1 → 1
2 → 2
3 → 3
4 → 4
5 → 5
6 → 6
7 → 0
8 → 1
9 → 2
10 → 3
Note how 0–3 are more common than 4–6; this is bias in your random number generation. (You're adding 1 as well, but that just shifts it over).
RAND_MAX of course isn't 10, but it's probably not a multiple of 7 (minus 1), either. Most likely its a power of two. So you'll have some bias.
I suggest using the Boost Random Number Library which can give you a random number generator that yields 1–7 without bias. Look also at bames53's answer using C++11, which is the right way to do this if your code only needs to target C++11 platforms.
Just another way:
float probs[5] = {1/7.0f, 1/7.0f, 2/7.0f, 2/7.0f, 1/7.0f};
float sum = 0;
for (int i = 0; i < 5; i++)
sum += probs[i]; /* edit */
int rand_M() {
float f = (rand()*sum)/RAND_MAX; /* edit */
for (int i = 0; i < 5; i++) {
if (f <= probs[i]) return i;
f -= probs[i];
}
return 4;
}
Assuming rand() is good then your code will work with only a very small bias to the lower X numbers, where X is RAND_MAX % 7. It's much more likely that you won't get the desired odds due to the quality of the implementation of rand(). If you find that to be the case then you'll want to use an alternative random number generator.
C++11 introduces the header <random> which includes several quality RNGs. Here's an example:
#include <random>
#include <functional>
auto rand = std::bind(std::uniform_int_distribution<int>(1,7),std::mt19937());
Given this, when you call rand() you will get a number from 1 to 7 each with equal probability. (And you can choose different engines if for different quality and speed characteristics.) You can then use this to implement the if-else conditions your example currently uses with std::rand(). However <random> allows you to do even better using one of their non-uniform distributions. In this case what you want is discrete_distribution. This distribution allows you to explicitly state the weights for each value from 0 to n.
// the random number generator
auto _rand = std::bind(std::discrete_distribution<int>{1./7.,1./7.,2./7.,2./7.,1./7.},std::mt19937());
// convert results of RNG from the range [0-4] to [1-5]
auto rand = [&_rand]() { return _rand() +1; };
int toohigh = RAND_MAX - RAND_MAX%7;
int random;
do {
random = rand();
while (random >= toohigh); //should happen ~0.03% of the time
static const int results[7] = {1, 2, 3, 3, 4, 4, 5};
random = results[random%7];
This should give numbers with a distribution as even as rand can handle, and without the big if switch.
Note this does have a theoretically possible infinite loop, but the statistical odds of it staying in the loop for even are minuscule. The odds of it staying in the loop twice is quite close to the odds of winning the California Super Lotto Jackpot. Even if every person on the planet got five random numbers, it probably wouldn't stay in the loop three times. (Assuming a perfect RNG.)
rand returns pseudo-random integral number:
Notice though that this modulo operation does not generate a truly
uniformly distributed random number in the span (since in most cases
lower numbers are slightly more likely), but it is generally a good
approximation for short spans.
Now, regarding the less-lengthy way, you can use switch-case construction, or a series of conditional operators ?: (which will make your code short and unreadable:).

Random number generator, C++

I know there is a bit of limitations for a random number generation in C++ (can be non-uniform). How can I generate a number from 1 to 14620?
Thank you.
If you've got a c++0x environment, a close derivative of the boost lib is now standard:
#include <random>
#include <iostream>
int main()
{
std::uniform_int_distribution<> d(1, 14620);
std::mt19937 gen;
std::cout << d(gen) << '\n';
}
This will be fast, easy and high quality.
You didn't specify, but if you wanted floating point instead just sub in:
std::uniform_real_distribution<> d(1, 14620);
And if you needed a non-uniform distribution, you can build your own piece-wise constant or piece-wise linear distribution very easily.
A common approach is to use std::rand() with a modulo:
#include<cstdlib>
#include<ctime>
// ...
std::srand(std::time(0)); // needed once per program run
int r = std::rand() % 14620 + 1;
However, as #tenfour mentions in his answer, the modulo operator can disrupt the uniformity of values std::rand() returns. This is because the modulo translates the values it discards into valid values, and this translation might not be uniform. For instance, for n in [0, 10) the value n % 9 translates 9 to 0, so you can get zero by either a true zero or a 9 translated to zero. The other values have each only one chance to yield.
An alternative approach is to translate the random number from std::rand() to a floating-point value in the range [0, 1) and then translate and shift the value to within the range you desire.
int r = static_cast<double>(std::rand()) / RAND_MAX * 14620) + 1;
srand() / rand() are the functions you need, as others have answered.
The problem with % is that the result is decidedly non-uniform. To illustrate, imagine that rand() returns a range of 0-3. Here are hypothetical results of calling it 4000 times:
0 - 1000 times
1 - 1000 times
2 - 1000 times
3 - 1000 times
Now if you do the same sampling for (rand() % 3), you notice that the results would be like:
0 - 2000 times
1 - 1000 times
2 - 1000 times
Ouch! The more uniform solution is this:
int n = (int)(((((double)std::rand()) / RAND_MAX) * 14620) + 1);
Sorry for the sloppy code, but the idea is to scale it down properly to the range you want using floating point math, and convert to integer.
Use rand.
( rand() % 100 ) is in the range 0 to 99
( rand() % 100 + 1 ) is in the range 1 to 100
( rand() % 30 + 1985 ) is in the range 1985 to 2014
( rand() % 14620 + 1 ) is in the range 1 to 14620
EDIT:
As mentioned in the link, the randomizer should be seeded using srand before use. A common distinctive value to use is the result of a call to time.
As already said, you can use rand(). E.g.
int n = rand() % 14620 + 1;
does the job, but it is non-uniform.
That means some values (low values) will occur slightly more frequently. This is because rand() yields values in the range of 0 to RAND_MAX and RAND_MAX is generally not divisible by 14620. E.g. if RAND_MAX == 15000, then the number 1 would be twice as likely as the number 1000 because rand() == 0 and rand() == 14620 both yield n==1 but only rand()==999 makes n==1000 true.
However, if 14620 is much smaller than RAND_MAX, this effect is negligible. On my computer RAND_MAX is equal to 2147483647. If rand() yields uniform samples between 0 and RAND_MAX then, because 2147483647 % 14620 = 10327 and 2147483647 / 14620 = 146886, n would be between 1 and 10328 on average 146887 times while the numbers between 10329 and 14620 would occur on average 146886 times if you draw 2147483647 samples.
Not much of a difference if you ask me.
However, if RAND_MAX == 15000 it would make a difference as explained above.
In this case some earlier posts suggested to use
int n = (int)(((((double)std::rand()) / RAND_MAX) * 14620) + 1);
to make it 'more uniform'.
Note that this only changes the numbers that occur more frequently since rand() still returns 'only' RAND_MAX distinct values.
To make it really uniform, you would have to reject any integer form rand() if it is in the range between 14620*int(RAND_MAX/14620) and RAND_MAX and call rand() again.
In the example with RAND_MAX == 15000 you would reject any values of rand() between 14620 and 15000 and draw again.
For most application this is not necessary. I would worry more about the randomness of rand().
Here's a tutorial using the boost library http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/tutorial.html#boost_random.tutorial.generating_integers_in_a_range
The rand() function is not really the best Random generator, a better way would be by using CryptGenRandom().
This example should do do the trick:
#include <Windows.h>
// Random-Generator
HCRYPTPROV hProv;
INT Random() {
if (hProv == NULL) {
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT | CRYPT_VERIFYCONTEXT))
ExitProcess(EXIT_FAILURE);
}
int out;
CryptGenRandom(hProv, sizeof(out), (BYTE *)(&out));
return out & 0x7fffffff;
}
int main() {
int ri = Random() % 14620 + 1;
}
the modulus operator is the most important, you can apply a limit with this modulus, check this 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

Random integers c++

I'm trying to produce random integers (uniformly distributed).
I found this snippet on an other forum but it works in a very weird way..
srand(time(NULL));
AB=rand() % 10+1;
Using this method I get values in a cycle so the value increases with every call until it goes down again. I guess this has something to do with using the time as aninitializer?
Something like this comes out.
1 3 5 6 9 1 4 5 7 8 1 2 4 6 7.
I would however like to get totally random numbers like
1 9 1 3 8 2 1 7 6 7 5...
Thanks for any help
You should call srand() only once per program.
Also check out the Boost Random Number Library:
Boost Random Number Library
srand() has to be done once per execution, not once for each rand() call,
some random number generators have a problem with using "low digit", and there is a bias
if you don't drop some number, a possible work around for both issues:
int alea(int n){
assert (0 < n && n <= RAND_MAX);
int partSize =
n == RAND_MAX ? 1 : 1 + (RAND_MAX-n)/(n+1);
int maxUsefull = partSize * n + (partSize-1);
int draw;
do {
draw = rand();
} while (draw > maxUsefull);
return draw/partSize;
}
You can use the the Park-Miller "minimal standard" Linear Congruential Generator (LCG): (seed * 16807 mod(2^31 - 1)). My implementation is here
Random integers with g++ 4.4.5
The C language 'srand()' function is used to set the global variable that 'rand()' uses. When you need a single sequence of random numbers, 'rand()' is more than enough, but oftentimes you need several random number generators. For those cases, my advice would be to use C++ and a class like 'rand31pmc'.
If you want to generate random numbers in a small range, then you can use the Java library implementation available here:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29