Gerar números aleatórios de forma eficaz com o rand()

Faça uma pergunta



Você deve ter notado que em C, usando a função rand() da biblioteca padrão, você obtém resultados decepcionantes, muitas vezes, os mesmos.
Vejamos um exemplo, você quer gerar 5 números aleatórios de uma vez:


#include <stdlib.h> 
#include <stdio.h> 

int main() 
{ 
    int i; 
    for(i=0; i<5; i++) 
    { 
        printf("%d\n", rand()); 
    } 
    return 0; 
}


Vamos executar este programa e ver o que ele nos escreve:
41 
18467
6334
26500
19169


Bom, são resultados significativamente diferentes. Mas se você reiniciar o seu programa, você terá a mesma série de números.


Para alterar o comportamento do gerador de números aleatórios, podemos alterar uma variável na qual ele se baseia para os seus cálculos. A isto chamamos de semente (ou seed).
Esta semente é alterada com a função srand():
srand(valor da semente)

É preciso um número que não seja fácil prever e que varie sempre de um momento para outro.

Por exemplo, você pode usar o número de ciclos utilizados pelo seu processador desde o início.
Ele pode ser obtido, em processadores x86 (Intel, AMD etc ...), com o comando assembler rdtsc.
O registro de uma função rdtsc() chamando esse comando em assembler poderá facilitar a sua vida, a seguinte sintaxe funciona com o gcc no Linux, você poderá reencontrar em outro lugar com o dev C++ no Windows.
#include <stdlib.h> 
#include <stdio.h> 

int rdtsc() 
{ 
    __asm__ __volátil__("rdtsc"); 
} 

int main() 
{ 
    int i; 
    for(i=0; i<5; i++) 
    { 
        srand(rdtsc()); 
        printf("%d\n", rand()); 
    } 
    return 0; 
}


Com esse código, você já terá números aleatórios mais eficazes.
Atenção, esta solução só funciona em processadores x86. Se o seu programa precisar ser portável para outras arquiteturas de processadores, você deverá considerar outra coisa.
Além disso, não ative otimizações no compilador (opção -O1,-O2, O3, etc ...) se você usar esta função rdtsc, você poderá ter um comportamento estranho ....