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();