Newsgroup: it.comp.lang.c
Titolo: problema di random

Ciao a tutti... ho iniziato da pochi giorni a programmare in C e diciamo 
che sono vittima degli ovvi primi problemi... 
sto imparando passo per passo. 
Ho provato oggi a fare il classico gioco del lancio dei dadi. Mi succede 
perň un piccolo problema. 
Ora copio la funzione che ho sviluppato per la simulazione
int lancio(void)
{
 int risultato;
 float parziale;
 parziale=rand()/32768;
 risultato=1+ (int)(6*parziale);
 printf("Risultato: %d", risultato);
}
Il risultato della variabile "parziale" č sempre 0.000000 e non ne 
capisco il motivo. Il risultato del lancio č quindi sempre 1.
ho provato a fare anche un semplice parziale=rand(); cosě, di prova e il 
risultato č sempre lo stesso... 247 se non erro. Ma non vorrei 
sbagliarmi. 
Credo ci sia qualche problema nella funzione random.
Ho inoltre aggiungo srand all'inizio della main() per inizializzare, ma 
nulla ancora. Unica soluzione il lancio dei dadi risulta pari a 2.
Mah... sapete darmi una mano?
-- 
-Diego (Atos)-
-L'uomo č superiore agli animali-
-(Fanno eccezione il nano e la giraffa)
-Alessandro Bergonzoni-
-Togliere NOSPAM per la risposta in privato-

 
La butto la': non e' che rand crea numeri x con 0<x<1 e che il livello di 
precisione di default e' di 6 cifre e dividendo per 32etc quindi approssima 
sempre a 0?
-- 
Gavrila
Registered Linux User
#276811
http://counter.li.org

 }
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Woe to you, Oh Earth and Sea,
 for the Devil sends out the beast with wrath,
 because he knows the time is short...
 Let him who had understanding reckon the number of the beast
 for it is a human number, its number is Six hundred and sixty six."
Revelations ch XIII, b. 18

 di prova e il risultato è sempre lo stesso... 247 se non erro.
Il risultato è sempre lo stesso perché il seed è settato a 1 se non lo
modifichi tu.
Maurizio.

capisco il motivo.
Secondo me usi Windows, quindi RAND_MAX varra' 32k, esattamente la
costante per cui dividi.
Ora se e' come penso la rand() ritorna valori tra 0 e 32768. Fare la
divisione intera tra il risultato della rand() e 32768 sara' in 32768
casi uguale a 0 e in un caso uguale a 1. La divisione tra interi
infatti tronca tutta la parte decimale.
Ora, vorrei sapere cosa devi ottenere esattamente.
Se volevi un numero casuale tra [0, 1] distribuito uniformemente devi
fare:
double rnd = (double)rand() / RAND_MAX
Ora devi solo scegliere il modo per ottenere il tuo risultato, in
pratica devi scegliere un metodo per arrotondare a int il risultato.
Es.
(int)(rnd * 6) mi dara' numeri tra 0 e 6 (con probabilita' di 1 su
RAND_MAX per il 6).
Per correggere questo problema basta cambiare la definizione di rnd,
in modo che il suo valore sia compreso tra [0, 1[ (estremo destro
escluso):
double rnd = (double)rand() / (RAND_MAX-1)
Ora hai tolto anche quella probabilita' di 1 su RAND_MAX che uscisse 1
:P
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 operandi a float (o double):
Tuttavia non ho la funzione Rand_max
Io uso il dev come compilatore e devo programmare in ambiente DOS, può 
essere questo il problema?
Come cavolo si fa a lancire sto dado porco cane? eheh
grazie ancora
ciao
-- 
-Diego (Atos)-
-L'uomo è superiore agli animali-


 modifichi tu.
Modificare il seed?
Cioè devo impostare in questo modo?
#define seed 12345;
(l'avevo letto da qualche parte, ma dove non ricordo)
e poi nella funzione devo inserire la stringa:
srand(seed);
corretto?
così mi cambia solo il valore estratto dal rand, ma non sono ancora 
casuali (anche perchè è sempre lo stesso... porcaccia!)
ciao 
-- 
-Diego (Atos)-
-L'uomo è superiore agli animali-


Tuttavia non ho la funzione Rand_max
No, RAND_MAX e' una costante definita in limits.h


Modificare il seed?
Per avere una generazione pseudocasuale:
srand((unsigned)time(NULL));
Ma attenzione, potresti avere sfiga in questo modo, non tutti i numeri
sono dei "buoni" seed, ma e' molto portabile e molto semplice.



In *Numerical Recipes in C: The Art of Scientific Computing* (William H. Press,
Brian  P.  Flannery,  Saul  A. Teukolsky, William T. Vetterling; New York:
Cambridge University Press, 1992 (2nd ed., p. 277)), the following comments are
made:
	"If you want to generate a random integer between 1 and 10, you should
	always do it  by  using  highorder bits, as in
		j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
	and never by anything resembling
		j=1+(rand() % 10);
	(which uses lower-order bits)."
Random-number generation is a complex topic.  The *Numerical Recipes in C* book
(see reference above) provides an excellent discussion of practical random-
number generation issues in Chapter 7 (Random Numbers).
---
..dovrebbe bastarti...
Adieu,
-- 
Lestat de Lioncourt                               |          Ciro Mattia Gonano
  JabberID: 
les...@jabber.students.cs.unibo.it
    |    Undergraduate Student in
  ICQ#: 52631406                                  |         Computer Science at
  URL: 
http://www.CS.UniBO.It/~gonano
             |       University of Bologna
            <powered by Linux Slackware 8.1 on Kernel 2.4.18-xfs>

 
Ho #incluso nel prog limits.h , ma nulla
l'ho scorso tutto ma non c'è alcuna costante "rand_max"
Mi sa che il mio Dev 4 è un po' vecchio... mmm....
Comunque io sti dadi non riesco ancora a lanciarli... 
Anche perchè se rand_max è una costante non credo risolva il mio 
problema... a me non genera numeri casuali... perchè se al posto di 
rand_max metto valori diversi numerici il risultato cambia...ma ad ogni 
esecuzione è sempre il medesimo. 
Deve esserci altro che non va, cavolo... 
(con il buon vecchio pascal era così semplice! eheh)


 
Ti rnigrazio. La stringa la so, purtroppo. Ma come ho risposto a Mox il 
mio problema è proprio un altro... 


 Mi sa che il mio Dev 4 č un po' vecchio... mmm....
Infatti non č detto che la costante si trovi per forza in limits.h. Il mio
compilatore (IBM) la riporta in stdlib.h.
Comunque RAND_MAX č tutto in maiuscolo. Fai attenzione che il C č case
sensitive.
Facciamo cosě: ti riporto tutto il programma. Tu lo devi solo copiare e
incollare e poi ci dici cosa non funziona.
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    int lancio(void) {
        int risultato;
        risultato = 1 + (int)(6.0 * rand() / (RAND_MAX + 1.0));
        printf("Risultato: %d\n", risultato);
        return risultato;
    }
    int main(void) {
        int i;
       srand(time(NULL));
       for (i = 0; i < 10; i++)
          lancio();
       return 0;
}
Maurizio.

 rand_max + 1... perchè? 
grazie di tutto
ciao
p.s.
ce l'ho fatta a lanciare sto dado finalmente!


compilatore (IBM) la riporta in stdlib.h.
Invece e' proprio detto che hai ragione tu :P  E' in stdlib.h, non in
limit.h: sono andato a memoria e ho sbagliato.


> rand_max + 1... perchè? 
Statistica: serve per impedirti di ottenere il valore 1.0, limitandoti
a un valore massimo di 0.(9) inteso come 9 periodico (scusa, ma
l'unica notazione che rende in asci e' questa ed e' orribile).
Tra l'altro nel post precedente mi dev'essere scappato un -1 al posto
del +1.
Provo a spiegare con 1 esempio.
Supponi per comodita' che rand() ritorni valori tra 0 e 10, RAND_MAX
varra' 10.
Analizziamo qualche caso:
 0 / ogni_numero = 0
10 / 10          = 1 resto  0 --> 1.0        CASO: senza sommare 1
10 / (10-1)      = 1 resto  1 --> 1.(1)      CASO: mio errore di typo
 9 / (10-1)      = 1 resto  0 --> 1.0        CASO: mio errore di typo
10 / (10+1)      = 0 resto 10 --> 0.(90)     CASO: corretto
E' importante che il risultato nel caso del risultato maggiore (ovvero
in cui rand() restituisce RAND_MAX) sia minore di 1, altrimenti il
calcolo: 1 + N*rnd, darebbe come risultato N+1, mentre tu volevi solo
numeri tra 1 e N.
Detto piu' formalmente: il generatore di numeri casuali genera un
numero distribuito uniformemente nell'intervallo [0, 1[ (leggi tra 0
incluso fino a 1 escluso).
Prova a fare qualche simulazione, anche per i risultati intermeti e
poi nei casi estremi, soprattutto considera il risultato delle varie
operazioni di conversione a INT possibili, tra cui la piu' immediata
e' il cast.


 del +1.
Si si... avevo intuito.
Sia l'errore che la spiegazione. Appena inviato il post mi è sovvenuta 
la soluzione automaticamente
Grazie a tutti...
Al prossimo intoppo (ce ne saranno tanti... essendo all'inizio)
ciao
