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.
link
link
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?