Não consigo entender essa parte do código [RESOLVIDO]

1. Não consigo entender essa parte do código [RESOLVIDO]

INFER
nkio

(usa Ubuntu)

Enviado em 10/08/2013 - 09:31h

Vou escreve o que está no livro para ficar mais claro:

"Para demonstrar rand, desenvolveremos um programa que simulará 20 lançamentos de um dado de seis lados e exibirá o valor de cada lançamento. O protótipo de função para a função rand está em <stdlib.h>. Usaremos o operador de módulo (%) em conjunto com rand da seguinte forma:

rand() % 6

para produzir inteiros no intervalo de 0 a 5. Isso é chamado de ESCALA. O número 6 é chamado de de FATOR DE ESCALA. Depois, DESLOCAMOS o intervalo de números produzidos somando 1 ao nosso resultado anterior. A saída da figura 5.7 confirma que os resultados estão no intervalo de 1 a 6 - a saída poderia variar conforme o compilador,

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

int main(void)
{
int i;

for (i = 1; i <= 20; i++) {
printf("%10d", 1 + (rand() % 6));

if (i % 5 == 0) {
printf("\n");
}
}

return 0;
}



Alguém pode me explicar isso? Eu quero dizer que eu só venho aqui, quando não consigo entender de maneira alguma, sei que podem pensar que eu sou algum preguiçoso, mas eu tô me esforçando, e travei nessa parte!

Não entendi o que é "escala", e não entendi o que é "fator de escala". Não entendi o porque de rand() % 6.

Eu não sou lá essas coisas em matemática, agora que eu estou me esforçando mais pra entendê-la, tenho 14 anos, tem muita coisa na minha cabeça, então por isso peço ajuda de vocês. rsrs!!

Tenho que fazer muitas coisas ao mesmo tempo...


  


2. Re: Não consigo entender essa parte do código [RESOLVIDO]

wellington
wellingtonsr

(usa Slackware)

Enviado em 10/08/2013 - 11:37h

Não sou muito bom em C, mas...Aqui "(rand() % 6)" é pra ele gerar números aleatórios de 0 até 6. Para gerar de 1 até 6 usá-se o "1 +" na frente do (rand() % 6), ficando assim "1 + (rand() % 6)"



3. Re: Não consigo entender essa parte do código [RESOLVIDO]

Diego Langer
dlanger

(usa Debian)

Enviado em 10/08/2013 - 11:41h

Você esta certo wellingtonsr.
Neste caso a escala é de 1 a 6, como você explicou. Substitua o 6 por qualquer outro número, ex: 10, e você percebera que agora os 20 valores gerados estarão na faixa entre 1 e 10.


4. Re: Não consigo entender essa parte do código [RESOLVIDO]

Bruno Rogério Fernandes
brunorf

(usa Arch Linux)

Enviado em 10/08/2013 - 11:57h

Olha wellingtonsr, na verdade não é bem o que você escreveu.
A função rand() gera um número aleatório entre 0 e RAND_MAX, definido em stdlib.h.

Assim, caso queiramos um valor entre 0 e 5, por exemplo, precisamos do operador módulo (%), que retorna o resto da divisão de um operando pelo outro. Ou seja, se fizermos rand() % 6 obteremos o resto da divisão de um número entre 0 e RAND_MAX por 6, cujos valores possíveis são: 0, 1, 2, 3, 4 e 5. Portanto rand() % 6 retorna um número aleatório no conjunto [0,1,2,3,4,5], e não no conjunto [0,1,2,3,4,5,6] como você escreveu.

Então, para que o intervalo seja deslocado para a direita, basta somar 1 ao resultado: 1 + rand() % 6. Assim o conjunto de números possíveis será [1,2,3,4,5,6].

Para mais detalhes sobre a função rand() consulte man 3 rand.


5. Re: Não consigo entender essa parte do código [RESOLVIDO]

wellington
wellingtonsr

(usa Slackware)

Enviado em 10/08/2013 - 12:35h

brunorf escreveu:

Olha wellingtonsr, na verdade não é bem o que você escreveu.
A função rand() gera um número aleatório entre 0 e RAND_MAX, definido em stdlib.h.

Assim, caso queiramos um valor entre 0 e 5, por exemplo, precisamos do operador módulo (%), que retorna o resto da divisão de um operando pelo outro. Ou seja, se fizermos rand() % 6 obteremos o resto da divisão de um número entre 0 e RAND_MAX por 6, cujos valores possíveis são: 0, 1, 2, 3, 4 e 5. Portanto rand() % 6 retorna um número aleatório no conjunto [0,1,2,3,4,5], e não no conjunto [0,1,2,3,4,5,6] como você escreveu.

Então, para que o intervalo seja deslocado para a direita, basta somar 1 ao resultado: 1 + rand() % 6. Assim o conjunto de números possíveis será [1,2,3,4,5,6].

Para mais detalhes sobre a função rand() consulte man 3 rand.



blz. como disse, não sou muito bom em C.

Então:

rand % 6 => 0,1,2,3,4,5
1 + (rand % 6) => 1,2,3,4,5,6
2 + (rand % 6) => 2,3,4,5,6,7
3 + (rand % 6) => 3,4,5,6,7,8


Ou seja, desloca uma casa?

O 6 da expressão (rand % 6) é a quantidade de dígitos gerados.





6. ATENÇÃO: Deram-lhe a explicação ERRADA!

Paulo
paulo1205

(usa Ubuntu)

Enviado em 10/08/2013 - 23:37h

Vamos por partes?

Fator é cada um dos termos numa operação de multiplicação. Assim sendo, a multiplicação 4×7 tem dois fatores: 4 e 7. E a multiplicação 1×2×3×4×5 tem cinco fatores: 1, 2, 3, 4 e 5.

Escala é um tipo de régua usada para indicar não as dimensões reais de um objeto, mas sim uma representação proporcional, geralmente em papel ou em tela, dos objetos representados. Se você algum dia já olhou um mapa, por exemplo, deve ter reparado na indicação de escala (uma reguinha próxima à legenda, indicando quantos quilômetros são representados em cada centímetro). Usando esse exemplo, numa mapa com escala 1:2000 (lê-se "1 para 2000"), um quarteirão retangular com 50m por 100m seria representado no mapa como um retângulo de 2,5cm por 5cm, e um riacho com dois metros de largura seria representado com apenas 1mm de largura no mapa.

A escala, em si, já é uma indicação de fator. No exemplo do mapa, acima, as medidas reais do quarteirão e do riacho foram divididas por 2000 para serem representadas no mapa. Só que você pode sempre transformar uma divisão numa multiplicação (e vice-versa): a÷b é a mesma coisa que a×(1÷b) (e c×d é o mesmo que c÷(1÷d)). Essa correspondência fica evidente até na nossa linguagem cotidiana: "o mapa é 2000 vezes menor que a realidade" -- onde "vezes menor" ou "vezes menos" indica uma divisão. Dividir por 2000 é a mesma coisa que multiplicar por 1÷2000 (que vale 0,0005).

O problema é que a explicação que lhe foi dada está ERRADA, pois o programa não está realmente aplicando um fator de escala. Não se tem um fator porque não se tem uma multiplicação nem uma divisão que possa ser transformada numa multiplicação. Também não se tem escala, porque o resultado da operação de obter o resto é não é proporcional ao dividendo, mas cíclica para valores consecutivos do dividendo, com período de repetição limitado pelo divisor.

Ainda que, em C, a expressão r=x%y signifique "obter o resto da divisão inteira de x por y e gravar o valor em r", você não conseguiria expressar a mesma operação usando uma multiplicação, nem teria como reconstituir com certeza o valor de x tendo apenas r e y (por exemplo: se y valer 6 e r for igual a 1, você não teria como saber se x valia 1, 7, 31, 55, 6666666661, -5, ou -66666665).

A explicação correta, portanto, para o uso da forma rand()%N é que você utiliza Aritmética Modular (por isso, inclusive, o operador "%" é chamado de "módulo", em vez "obtentor do resto da divisão", embora não fosse errado chamá-lo desta última forma) para limitar os valores obtidos do gerador de números aleatórios (ou pseudoaleatórios) ao intervalo inteiro que vai de 0 a N-1.

Limitar a faixa de valores aleatórios usando módulo é uma forma rápida de se fazer, mas que tem problemas do ponto de vista matemático, principalmente quando a função geradora de números (pseudo)aleatórios não é muito boa. Muitas implementações de funções geradoras desses números utiliza internamente uma conta do tipo "x=A·x+B" para obter os sucessivos valores da sequência pseudoaleatória. Por si só, essa função interna já não produz bons números para algumas aplicações (por exemplo: criptografia), mas é comum assim mesmo porque é uma forma rápida de obter uma sequência que atende suficientemente bem a maioria das aplicações do dia-a-dia. No entanto, a qualidade dos números obtidos pode piorar muito dependendo da relação entre RAND_MAX, esses A e B internos e o valor de N usado na operação de módulo para limitar externamente os valores sorteados, seja reduzindo o período de repetição, seja causando uma maior concentração de números sorteados numa determinada faixa, e concentração mais baixa em outras faixas.

Por incrível que pareça, usar uma fator de escala de verdade é uma forma minimizar esses efeitos deletérios. Assim, para obter um número inteiro (pseudo)aleatório na faixa [MIN, MAX] (sendo MIN e MAX constantes também inteiras), em lugar de fazer

/* solução usando módulo (ruim) */
const int distancia=MAX-MIN+1;

int valor_sorteado;

valor_sorteado=MIN+(rand()%distancia);


é melhor fazer deste modo:

/* solução usando fator de escala (melhor) */
const double fator=(MAX-MIN+1.0)/(1.0+RAND_MAX);

int valor_sorteado;

valor_sorteado=MIN+fator*rand();







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts