# How to generate large random numbers in C ++?

7

I'm trying to make a random number generator of [0,4], including these, but the problem is my teacher indicated that I used 4 million to generate random numbers and that value exceeds% with% / strong>, then there are two questions:

• How to generate% random numbers%?
• How to generate random with an interval greater than `RAND_MAX` ?
• Code:

``````#include <cstdlib>
#include <set>
#include <iostream>
#include <windows.h>
#include <time.h>
#include <vector>

using namespace std;

int main(int argc, char** argv) {
double populacao;
double aptidao;
srand((unsigned) time(NULL));

for(int i=0; i<10; i++) {
populacao[i]=(((rand()%400000)/4000000.0)*4);
cout<<populacao[i]<<endl;
aptidao[i]=populacao[i];
}
system("Pause");
}
``````

asked by anonymous 16.08.2017 / 19:00

9

Depends on the compiler, probably using a bad one. See that reaches 2 billion . Of course, any compiler that manages at least 32767 is within the default.

If you do not need to be able to give all integers you can multiply until you reach the desired value.

If you're using C ++ 11 up, and should, then you can use the more modern C ++ library :

``````#include <iostream>
#include <random>
using namespace std;

int main() {
default_random_engine generator;
uniform_int_distribution<int> distribution(0, 4000000);
double populacao;
double aptidao;
for (int i = 0; i<10; i++) {
populacao[i] = distribution(generator);
cout << populacao[i] << endl;
aptidao[i] = populacao[i];
}
}
``````

See running on ideone . And at Coding Ground . Also I put GitHub for future reference .

Outside this you have to create more complex formulas or even use an alternate generator, which I do not find interesting in most cases.

16.08.2017 / 19:28
5

You have several options for generating very large numbers.

First, you can raffle multiple numbers and merge into one. But be careful not to create non-uniform generators and use them as if they are. For example, if `rand()` draws from 0 to 32767 (2 ^ 15-1), you can create the uniform generator

``````int rand2(){
int temp = rand() ; // Sorteia uniformemente número de 0x0000 a 0x7FFF
temp <<= 15 ;       // Agora é de 0x00000000 a 0x3FFF8000, múltiplo de  0x8000
temp += rand() ;    // Agora é sorteio uniforme de 0x00000000 a 0x3FFFFFFF
return temp ;
}
``````

to sort from 0 to 1073741823 (2 ^ 30-1) or you can also use

``````long long int rand3(){
long long int temp = rand2() ; // Sorteia uniformemente número de 0x0000 a 0x3FFFFFFF
temp <<= 15 ;                  // Agora é de 0x00000000 a 0x1FFFFFFF8000, múltiplo de  0x8000
temp += rand() ;               // Agora é sorteio uniforme de 0x00000000 a 1FFFFFFFFFFF
return temp ;
}
``````

to sort from 0 to 35184372088831 (2 ^ 45-1), also uniformly. Another option is to create your own congruent linear generator of pseudo-random numbers (same methodology used by libraries) with a wikipedia orientation. So you can make a randomizer the way you like.

The following, for example, I just created to answer your question. I do not know if it generates quality because I have not tested it, but it actually generates numbers from 0 to 4294967295 (2 ^ 32-1), probably performs better than previous ones, and does not have to call `srand()` to generate randomness uses by default as the seed the clock), but also does not accept seed specification in case it needs.

``````# include <time.h>
unsigned int random(){
static long long unsigned int state = time(0) ;     // Estado inicial (semente)
state = 0x23A7489B29LL + 0x50FB738205C1LL * state ; // Atualizar estado atual
return (unsigned int)( state>>32 ) ;                // Gerar a partir do estado
}
``````

If you want to find a suitable way, you can even create generators that generate `long long unsigned int` numbers ranging from 0 to 18446744073709551615 (2 ^ 64-1), but for this you need something better worked out using more than one state variable.

As for the generation of large numbers, it has an absurdly large number of options. As far as generating numbers of type `double` , I do not know if that's what you want to know, but the most common way of doing this is `rand()/(RAND_MAX+1.0)` , which will uniformly sort numbers `double` ranging from 0.000 (including -o) to 1,000 (excluding it).

You can make adaptations for better raffle quality, higher performance, and different properties (such as 1,000 or 0,000 excluded). In my opinion, a good way to sort `double` is as follows, which modifies the code of `random()` created earlier to make a uniform and continuous draw between two numbers of type `double` .

``````# include <time.h>
double random( double number1 , double number2 ){
static long long unsigned int state = time(0) ;                             // Estado inicial (semente)
state = 0x23A7489B29LL + 0x50FB738205C1LL * state ;                         // Atualizar estado atual
double zeroToOne ;
*(long long unsigned int*)&zeroToOne = ( state>>12 )+0x3FF0000000000000LL ; // Gerando número de 0.0 a 1.999999999999999778
zeroToOne -= 0.999999999999999889 ;                                         // Agora é de 0.000000000000000111  a 0.999999999999999889
return number1*( 1.0-zeroToOne )+( zeroToOne )*number2 ;                    // Retorna um número aleatório que vai de number1 a number2
}
``````

According to tests I did years ago, it performs better than doing division with typecast implicitly. It is mathematically good because it has high granularity, thus well portraying the continuity property of the draw.

Any questions?

18.08.2017 / 03:26
2

The function `rand()` is able to return integers in the range between `0` and `RAND_MAX` .

It is guaranteed by default that `RAND_MAX` never has a value less than `32.767` , which causes `rand()` to always return a random number of at least `15 bits` .

The default `C99` ensures that `unsigned long long` has at least `64 bits` , that is, the range between `0` and `18.446.744.073.709.551.615` .

Starting from these premises, if each call of the function `rand()` is able to return me `15 bits` random, with 5 calls I am able to accumulate `75 bits` .

With proper logical processing, you can "mount" a random number of `64 bits` , with a portable implementation `C99` , let's see:

``````unsigned long long llrand( void )
{
unsigned long long ret = 0;

for( int i = 0; i < 5; i++ )
{
ret = (ret << 15) | (rand() & 0x7FFF);
}

return( ret & 0xFFFFFFFFFFFFFFFFULL );
}
``````

Test code:

``````#include <cstdlib>
#include <iostream>
#include <ctime>

unsigned long long llrand( void )
{
unsigned long long ret = 0;

for( int i = 0; i < 5; i++ )
{
ret = (ret << 15) | (std::rand() & 0x7FFF);
}

return( ret & 0xFFFFFFFFFFFFFFFFULL );
}

int main( void )
{
std::srand(std::time(NULL));

for( int i = 0; i < 20; i++ )
{
std::cout << llrand() << std::endl;
}

return 0;
}
``````

Output:

``````\$ ./rand64
8105869587383598689
6277277725189066831
1509360212795395722
1130692503851307412
14335258242796316152
5075740159224506903
14680498390136040740
7165466167364905026
16797692089103744121
16486198844466236119
7276392683204141714
8357279606092084573
16367915918020953270
16380497907074646611
16976708914435940256
10292415635872591979
13954955472883015315
6877101750998155002
11106815715087335245
5831095514054045134
``````

16.08.2017 / 20:41