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