Ir ao conteúdo

Posts recomendados

Postado

Preciso criar um programa que gere cartelas de 5x5 com números aleatórios entre 1 e 99, salvar em um arquivo .bin e também utilizar a função a seguir.
 

int random_number(int min_num, int max_num){
       int result = 0, low_num = 0, hi_num = 0;
 
       if (min_num < max_num){
           low_num = min_num;
           hi_num = max_num + 1; // include max_num in output
       } else {
           low_num = max_num + 1; // include max_num in output
           hi_num = min_num;
       }
 
       srand(time(NULL));
       result = (rand() % (hi_num - low_num)) + low_num;
       return result;
   }

 

 

O problema é que não estou compreendendo essa função, se alguém tiver uma dica sobre.

 

  • Curtir 1
Postado
3 horas atrás, Mario3210 disse:
int random_number(int min_num, int max_num){
       int result = 0, low_num = 0, hi_num = 0;
 
       if (min_num < max_num){
           low_num = min_num;
           hi_num = max_num + 1; // include max_num in output
       } else {
           low_num = max_num + 1; // include max_num in output
           hi_num = min_num;
       }
 
       srand(time(NULL));
       result = (rand() % (hi_num - low_num)) + low_num;
       return result;
   }

 

Você tentou ao menor rodar isso com alguns valores? pensou nisso?

 

Algo como incluir essas linhas
 

    if (min_num < max_num)
        printf( "%d + rand() %% %d\n", min_num, (max_num + 1 - min_num));
    else 
        printf("%d + rand() %% %d\n", 
            max_num+1, (min_num - max_num + 1));

 

e ver o que sai?

 

Esse código não está bom.

 

O if trata  o caso de a função ser chamada com valores invertidos, com o mínimo maior que o máximo, e de certa forma inverte os valores. Mas não é simétrico, então eu diria que está errado apenas. O if deveria tornar equivalentes 
 

    random_number(10, 18);
    random_number(18, 10);

 

Só que não faz. Porque simplesmente não inverte os valores? Do modo como está a primeira retorna entre 10 e 18 mas a segunda entre 11 e 19.

E se os valores forem iguais a função vai retornar sempre min_num + 1, de pouco uso. No caso de 10,10 retorna sempre 11, já que todo número é múltiplo de 1.

 

o srand() provavelmente está só errado aí. Em geral não há interesse ou vantagem em reiniciar o gerador a cada chamada. Isso é feito uma única vez no início dos sorteios. Nunca dentro da função geradora.

 

O valor de result também é meio bobinho já que podia retornar direto a expressão. 

 

Em relação à conta, é o óbvio: para escolher  números entre 1 e 8 se tem um intervalo de 7. Entre A e B o menor valor é A e o maior é B, já que o intervalo é inclusivo. Só que B-A é o tamanho do intervalo. Em geral se diz que o intervalo é fechado se ele inlcuir B, e se escreve [A,B]. Se B não fizesse parte do intervalo se diria que ele é aberto ao final --- open ended na literatura --- e se escreve [A,B) usando parênteses para indicar que é aberto no fim. Em C++ por exemplo todos os algoritmos --- <algorithm> --- trabalham assim, com sequências open-ended.

 

Um exemplo óbvio é o módulo:  A%B retorna uma sequência open-ended, entre 0 e B mas sem B, descrita [0,B)

x%8 retorna algo entre 0 e 7, a definição do resto da divisão de x por 8.  

 

Aplicando isso para A = 10 e B = 18 tem o que você viu aí: 18-10 = 8. x % 8 dá um número entre 0 e 7. Se você somar ao início do intervalo vai ter algo entre 10+0 e 10+7, e por isso a função soma 1 ao result... para incluir o final e ficar com [10,18]

 

A função equivalente

 

Essa função faz a mesma coisa que o exemplo, mas sem aquela "onda" toda. E sem chamar srand() dentro, que é bobagem.

 

int random_number(int min_num, int max_num)
{
    if (min_num < max_num)
        return min_num + rand() % (max_num + 1 - min_num);
    return (rand() % (min_num - max_num + 1)) + max_num + 1;
}

 

E não precisa de time(NULL) para iniciar rand() como parece que TODO MUNDO faz. Na verdade talvez seja melhor não usar em testes, porque é bom poder reproduzir a sequência.

 

Mas está tão errada quando a original. Talvez devesse retornar -1 ou cancelar o programa se o mínimo for igual ao máximo e inverter os valores se o mínimo for menor. Mais simples. E simétrico.

 

 

 

  • Curtir 1
Postado
random_number(1, 99)

Vai retornar um número de 1 a 99.

 

random_number(99, 1)

Vai retornar um número de 2 a 98.

 

Não acho que seja um erro, provavelmente o objetivo é fazer o aluno analisar a função e fazer a chamada da forma correta.

  • Curtir 2
Postado
6 horas atrás, Mario3210 disse:

O problema é que não estou compreendendo essa função, se alguém tiver uma dica sobre.

mas o que você não entendeu disso? comente o que entendeu seguido das linhas que entendeu e escreva não entendi isso seguido do que não entendeu... Basicamente, se você sabe que os numeros que entrar como parametro vão seguir a ordem, nem precisava desses testes dessas condicionais.

o usuário arfneto deu uma excelente solução para o que quer:
https://www.clubedohardware.com.br/forums/topic/1563959-gerar-valores-aleatórios-sem-repetição-em-uma-matriz/

 


Mas se achar complicado, ou considerar ilegivel, logo abaixo eu o mostro seu equivalente sem usar ponteiros.

  • Curtir 1
Postado
6 minutos atrás, JorgeGus disse:
random_number(1, 99)

Vai retornar um número de 1 a 99.

 

random_number(99, 1)

Vai retornar um número de 2 a 98.

 

Não acho que seja um erro, provavelmente o objetivo é fazer o aluno analisar a função e fazer a chamada da forma correta.

 

Acho que é só um erro mesmo. E ainda tem o caso dos valores iguais em que a função retorna uma constante. Não há qualquer razão na mudança de comportamento em 1 unidade. Como eu disse, o melhor seria simplesmente inverter os parâmetros quando A>=B. Essa diferença não leva a qualquer incentivo de correção por parte do aluno, ao menos não vejo um.

 

Nunca fiz um curso de C, mas espero que se um dia eu fizer não me deem "incentivos" assim

 

E tem a chamada a srand() dentro da função que gera os números é uma bobagem. E time(NULL) como semente num teste também não ajuda nada.

  • Curtir 1
Postado
Citação

E tem a chamada a srand() dentro da função que gera os números é uma bobagem. E time(NULL) como semente num teste também não ajuda nada.

Mas, novamente, as perguntas que não querem calar: por que? qual o contexto? e onde está a fonte?

 

professor da usp fazendo bobagem?
https://www.ime.usp.br/~pf/algoritmos/aulas/random.html


Mais:
https://www.cplusplus.com/reference/cstdlib/srand/

https://man7.org/linux/man-pages/man3/tsearch.3.html

https://classes.mst.edu/compsci1570/randomnumbergeneration.htm

http://linguagemc.com.br/valores-aleatorios-em-c-com-a-funcao-rand/

  • Curtir 1
Postado

Vamos discutir C, C++, C# ou algo técnico.

 

Poste o que quer dizer, ou ao menos um resumo do que tem nesses links.

 

7 horas atrás, codigo rápido disse:

por que? qual o contexto? e onde está a fonte?

 

sobre rand() a função gera uma sequência de números aleatórios, um novo número a cada chamada entre 0 e RAND_MAX. 

A ideia de srand() é gerar uma semente --- seed --- para a sequência. Como cada número é gerado a partir do anterior redefinindo a semente a sequência passa a se repetir.

 

E por isso vem essa ideia de usar time e passar o parâmetro NULL, por imaginar que o tempo não se repete e então a hora do sistema pode servir como semente para gerar uma sequência que não se reproduz, algo como um sorteio "honesto".

 

No entanto em teste ou mesmo em muitas situações de produção o que se quer é o contrário: ter uma sequência reprodutível de números aleatórios. O que NÃO se quer é compartilhar a semente. Mas a cada teste é super conveniente que os números sejam os mesmos.

 

Nesses últimos dias eu postei um exemplo completo em https://www.clubedohardware.com.br/forums/topic/1561085-funções-e-matrizes-isbn/?tab=comments#comment-8260096 onde 4 funções são usadas para um mesmo fim, e comparo os tempos para acho que uma série de 2 milhões de operações para cada função. É claro que se espera nesses casos que as 4 funções usem exatamente a mesma série de números, e serve como exemplo da importância de usar uma semente conhecida e NUNCA chamar srand() antes de cada chamada de rand(). 

 

Esse pode ser um tópico fora de contexto para discutir aqui, mas há um problema adicional relacionado à matemática: como os tempos vão estar muito próximos, usando time(NULL)  as sementes vão ser muito parecidas e isso pode influenciar muito na qualidade da sequência aleatória a ser gerada.

Estou apenas explicando. Muitas vezes falo de memória mesmo e não há razão para postar a fonte. É só uma opinião, e as fontes são bem conhecidas e muitas vezes o que falta é uma opinião dentro do contexto da pessoa que postou o problema.

  • Curtir 1
Postado
11 horas atrás, Mario3210 disse:

Preciso criar um programa que gere cartelas de 5x5 com números aleatórios entre 1 e 99, salvar em um arquivo .bin e também utilizar a função a seguir

 

Sobre isso eu postei um programa aqui em '19  nesse tópico --- e o programa está disponível para ver ou baixar aqui

 

Era um programa em C++ mas é bem simples de usar em C. Acho que você podia dar uma olhada.

 

O programa simula um bingo com umas cartelas e faz uma rodada na tela. Eis uma tela que tem lá dele rodando.

 

Conforme os números vão sendo sorteados vão aparecendo na lista embaixo e vão ficando verdes nas cartelas sorteadas. Não me lembro ao certo dos porques das coisas, mas era só para ajudar alguém nesse lance de sorteio e tela. Pode ser útil para você, já que tem cartelas e sorteios e tal.

 

image.png.9ba38aed3810f0773385a9fd65878767.png

 

Entendeu o que eu expliquei sobre a tal função, @Mario3210?

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!