Valor aleatório (Linguagem C)

Olá!
Alguém pode me ajudar a gerar um número aleatório entre 0 e 100?

Eu tava tentando com o módulo de rand() com 100, mas os números se repetem em outras execuções do programa. Alguém sabe explicar o porquê?
Há algum modo melhor de gerar um número aleatório?

Cara, tenta usar o srand(time(NULL)) antes do rand() para que a cada execução, o número gerado seja diferente

Ah, precisa importar a biblioteca <time.h>

Eu gostaria de ajuda pra entender o mecanismo, se possível.

Pq só rand() insiste em retornar os mesmo valores em cada execução?
No q consiste a função time()? (Já pesquisei no cplusplus.com)
E srand()? Como trabalha?
Melhor do que responder qualquer uma dessas perguntas: tem como eu ver a estrutura interna dessas funções? O corpo delas mesmo…

Sei que são perguntas bobas de amador, mas só uso C aqui e acolá…
Se alguém puder me ajudar, agradeço. =)

Acho que é mais fácil você, a partir do fonte das funções rand() e srand(), entender o que ocorre.

No meu compilador (Visual Studio 2005), rand() e srand() são definidas, respectivamente, como:


int __cdecl rand (void)
{
        _ptiddata ptd = _getptd();
        return( ((ptd->_holdrand = ptd->_holdrand * 214013L
            + 2531011L) >> 16) & 0x7fff );
}

void __cdecl srand (
        unsigned int seed
        )
{
      _getptd()->_holdrand = (unsigned long)seed;
}

Se eu disser que _getptd()->_holdrand pode ser substituída por uma declaração como a seguinte:

static unsigned long holdrand = 0L;

e o código acima

você acredita?

Se acreditar, o código de srand e rand seria equivalente a:


int rand (void)
{
        holdrand = (holdrand * 214013L + 2531011L);
        return (holdrand >> 16) & 0x7fff;
}

void srand (
        unsigned int seed
        )
{
      holdrand = (unsigned long)seed;
}

Você pode deduzir então que, se você não chamar srand com um número inicial qualquer (por exemplo, o horário atual em segundos), então o valor de holdrand vai ser zero, e o primeiro número retornado por rand() será 38 (faça as contas). O segundo valor será 30840, e assim por diante.

entaglement, vlw mesmo! =]
Gostei mto da resposta!

Como eu posso acessar os fontes das funções que quero a partir do dev? Dá?

Por favor, diga que você não está falando do DevCpp.

Não utilize essa IDE. Já ajudei diversos desenvolvedores que estavam com problemas aparentemente insolúveis, e que a real razão para sua dificuldade era o fato do devcpp omitir parte das mensagens de erro.
Além disso, o dev vem com uma versão pré-histórica do compilador C. Uma alternativa portável é o CodeBlocks. Outra é baixar o visual studio express.

Só a título de curiosidade, no C++11, você poderá gerar números aleatórios de 0 até 100 dessa forma:

[code]#include

int main(int argc, char* argv[]) {
//Usa o algorítmo mersenne twister - melhor, mais rápido e mais confiável que o do rand
std::mt19937 rng;
std::uniform_int_distribution<> ZeroAteCem(0,100);
int numero = ZeroAteCem(rng);
}[/code]

A biblioteca padrão incluirá diversos outros tipos de distribuição, como a de poisson, bernoulli ou a binomial.

tem razão, o problema dele é que a “semente” sempre é a mesma.

Oi ViniGodoy! Eu costumo usar o CodeBlocks em casa, mas na faculdade só tem o devcpp mesmo. =p
Quanto ao CodeBlocks, há como eu acessar o código fonte das funções de determinada biblioteca?

Quanto ao que foi sugerido aqui, no seginte código:

srand(time(NULL)); printf("%d\n", rand()); printf("%d\n", rand());

O segundo número sempre aparece maior que o primeiro.
Isso n me parece mto aleatório. =~
Explicações? To esquecendo algo?

Você não fez testes suficientes. Rode seu programa mais vezes e vai ver que ele pode aparecer maior ou menor que o anterior.
Exemplo:

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

int main (int argc, char *argv[]) {
    int i;
	srand (time (NULL));
	for (i = 1; i <= 10; ++i) {
		printf ("%d\n", rand());
	}
}
5318
758
31851
1455
1005
2629
18040
27872
20118
14554
5331
10984
5004
32172
9495
18336
30489
16162
20628
22730

Como foi que você viu a implementação das funções pelo seu compilador entanglement?

EDIT: Dando um “Find Implementation” no nome da função, a implementação da mesma é exibida pelo Code::Blocks.

[quote=cake]Oi ViniGodoy! Eu costumo usar o CodeBlocks em casa, mas na faculdade só tem o devcpp mesmo. =p
Quanto ao CodeBlocks, há como eu acessar o código fonte das funções de determinada biblioteca?

Quanto ao que foi sugerido aqui, no seginte código:

srand(time(NULL)); printf("%d\n", rand()); printf("%d\n", rand());

O segundo número sempre aparece maior que o primeiro.
Isso n me parece mto aleatório. =~
Explicações? To esquecendo algo?[/quote]

Esses algoritmos todos são pseudo aleatórios. Até mesmo no mundo real não existe ambiente que possa proporcionar um evento 100% nesse quesito.
Você precisa melhorar o algoritmo para conseguir resultados melhores.

[quote=matheuslmota]Como foi que você viu a implementação das funções pelo seu compilador entanglement?

EDIT: Dando um “Find Implementation” no nome da função, a implementação da mesma é exibida pelo Code::Blocks.[/quote]

Alguém mais não conseguiu achar a implementação de rand() através do “Find Implementation” do Code::Blocks?
Aqui eu até acho a declaração… Mas implementação não. =/

[quote=cake][quote=matheuslmota]Como foi que você viu a implementação das funções pelo seu compilador entanglement?

EDIT: Dando um “Find Implementation” no nome da função, a implementação da mesma é exibida pelo Code::Blocks.[/quote]

Alguém mais não conseguiu achar a implementação de rand() através do “Find Implementation” do Code::Blocks?
Aqui eu até acho a declaração… Mas implementação não. =/[/quote]

Só dá pra visualizar a implementação se você tiver criado um projeto no codeblocks. Se você criar apenas um arquivo e não associá-lo à nenhum projeto, o codeblocks não acha as implementações do compilado. Experimente criar um projeto no codeblocks e adicione o arquivo que está testando e depois tente achar a implementação.

[quote=matheuslmota]
Só dá pra visualizar a implementação se você tiver criado um projeto no codeblocks. Se você criar apenas um arquivo e não associá-lo à nenhum projeto, o codeblocks não acha as implementações do compilado. Experimente criar um projeto no codeblocks e adicione o arquivo que está testando e depois tente achar a implementação.[/quote]

Vc consegue ver a implementação de rand()?
Aqui continua dando not found…

[quote=cake][quote=matheuslmota]
Só dá pra visualizar a implementação se você tiver criado um projeto no codeblocks. Se você criar apenas um arquivo e não associá-lo à nenhum projeto, o codeblocks não acha as implementações do compilado. Experimente criar um projeto no codeblocks e adicione o arquivo que está testando e depois tente achar a implementação.[/quote]

Vc consegue ver a implementação de rand()?
Aqui continua dando not found…[/quote]

Pois é, eu vi aqui. Eu conseguia ver as implementações somente de métodos que são implementados nos arquivos .h e não nos .cpp o que quer dizer que de fato não dá pra ver os arquivos de source do compilador. E o rand não é esse caso.
Não sei como o entaglement viu essa implementação pelo compilador dele.

Se for usar alguma variação do gcc / mingw e baixar seus fontes, provavelmente vai ter também os fontes das bibliotecas usadas pelo C.

Se for usar o MS Visual Studio, que é o compilador que tenho de usar no dia-a-dia (argh), algumas das versões (as pagas com certeza, não sei quanto às gratuitas) vêm também com os fontes das bibliotecas. Elas ficam no subdiretório “CRT” (C++ Runtime).

[quote=matheuslmota][quote=cake][quote=matheuslmota]
Só dá pra visualizar a implementação se você tiver criado um projeto no codeblocks. Se você criar apenas um arquivo e não associá-lo à nenhum projeto, o codeblocks não acha as implementações do compilado. Experimente criar um projeto no codeblocks e adicione o arquivo que está testando e depois tente achar a implementação.[/quote]

Vc consegue ver a implementação de rand()?
Aqui continua dando not found…[/quote]

Pois é, eu vi aqui. Eu conseguia ver as implementações somente de métodos que são implementados nos arquivos .h e não nos .cpp o que quer dizer que de fato não dá pra ver os arquivos de source do compilador. E o rand não é esse caso.
Não sei como o entaglement viu essa implementação pelo compilador dele. [/quote]

Vocês poderiam usar o qtcreator. Ele possui todas essas documentações.

por exemplo rand()(POSIX.1-2001 )

[code]
static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
next = seed;
}[/code]