paulo1205
(usa Ubuntu)
Enviado em 01/07/2013 - 14:15h
paulosouza escreveu:
Eu sei usar, mas eu não conseguindo. Você poderia fazer e depois explicar para mim?
Desculpe pela franqueza, mas se você não está conseguindo, é porque não sabe usar.
Vamos lá:
rand () devolve um valor inteiro longo na faixa [0,
RAND_MAX ]. Se você quiser que esse valor fique na faixa [
M ,
N ], então você terá de usar uma expressão
a*x+b .
x é o valor devolvido por
rand() , e
a e
b devem ser escolhidos de modo tal que quando
x for zero, a expressão produza o valor mínimo (
M ) da faixa desejada, e que quando
x valer
RAND_MAX , o valor produzido seja
N .
Você terá, então, um sistema de duas equações e duas incógnitas, a saber:
a*0+b=M
a*RAND_MAX+b=N
De cara se vê que
b=M , e, portanto,
a=(N-M)/RAND_MAX .
Cuidado, porém, com a ordem em que você faz as contas e com os tipos de dados envolvidos, que podem ter limites facilmente extrapolados. Se você trabalhar só com inteiros, se fizer primeiro
rand()/RAND_MAX , para depois multiplicar por
N-M , vai ter quase sempre um valor 0 (exceto quando
rand () devolver exatamente
RAND_MAX , quando então essa divisão dará 1). Por outro lado, se você multiplicar primeiro, e
RAND_MAX for de uma ordem de grandeza comparável a INT_MAX, é possível que um valor muito grande devolvido por
rand () produza um overflow ao ser multiplicado por
(N-M) . Por isso mesmo, eu recomendo trabalhar com
a e
b como
double , da seguinte forma.
const double scale_factor=(double)(UPPER_LIMIT-LOWER_LIMIT)/(double)RAND_MAX;
const double offset=(double)LOWER_LIMIT;
double random_var;
int random_int_var;
random_var=scale_factor*(double)rand()+offset;
random_int_var=(int)(scale_factor*(double)rand()+offset+0.5); /* usa arredondamento */
Algumas pessoas podem recomendar que você use outra forma de calcular, usando a formula
x%(N-M+1)+M . Isso, no entanto, tem alguns problemas -- que eu mesmo já vivi na prática e posso atestar que existem --, porque alguns geradores de números pseudo-aleatórios de uso mais comum, usados internamente por
rand (), não variam de modo equilibrado os bits de mais baixa ordem e os de mais alta ordem, e a operação de extrair o resto da divisão de
x por
N-M+1 acaba ficando "viciada", com ciclos de repetição mais curtos, pois pega somente os bits de mais baixa ordem. A primeira forma que eu sugeri, usando números de ponto flutuante, é mais segura nesse sentido.