You have several options to generate very large numbers.
First, you can draw multiple numbers and merge into one. But be careful not to create non-uniform generators and use as if they were. For example, if the rand()
draw from 0 to 32767(2 15-1), you can create 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 draw 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 draw from 0 to 35184372088831 (2 45-1), also uniformly. Another option is to create your own linear congruent generator of pseudo-random numbers (the same methodology used by libraries) with a wikipedia orientation. So you can make a randomizer the way you prefer.
https://en.wikipedia.org/wiki/Linear_congruential_generator
https://en.wikipedia.org/wiki/Linear_congruential_generator
The following, for example, I have just created to answer your question. I don’t know if it generates quality because I haven’t tested it, but it actually generates uniformly numbers from 0 to 4294967295 (2 32-1), probably has more performance running than the previous ones and doesn’t need it to call srand()
to generate randomness (uses by default as seed the clock), but also does not accept Seed specification in case of need.
# 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 and find a suitable way, you can even create generators that generate type numbers long long unsigned int
ranging from 0 to 18446744073709551615 (2 64-1), but for this it needs something better worked using more than one state variable.
As for the generation of large numbers, it has an absurdly large number of options. As for the generation of numbers of type double
, I don’t know if that’s what you want to know, but the most common way to do that is rand()/(RAND_MAX+1.0)
, that will draw uniformly type numbers double
ranging from 0,000 (including) to 1,000 (excluding).
You can make adaptations for better draw quality, higher performance and different properties (such as including the 1,000 or excluding the 0,000). In my opinion, a good way to draw double
is the following, which modifies the code of the random()
previously created to make uniform and continuous draw between two type numbers 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, has better performance than doing the split with implicit Typecast. It is mathematically good because it has high granularity, thus portraying well the continuity property of the draw.
Any doubt?
Who generates random numbers is the implementation of the default API at runtime, not the compiler.
– Victor Stafusa
But it depends on which compiler the API will use. I spoke in the sense of the set. , not that it is the compiler that does this.
– Maniero