|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2010
Città: (MB)
Messaggi: 11971
|
[C] funzione rand()
Ho bisogno di fare il programma stupido del lancio della moneta, ho provato ad utilizzare la rand(), ma purtroppo ad ogni run del programma, mi genera lo stesso numero e quindi esce sempre croce, com'è possibile sto fatto? come faccio a generare numeri diversi all'interno di un intervallo da me imposto??
__________________
CPU: Ryzen 3700x DISSY: CM HYPER EVO 212 RAM: 16gb DDR4 3000Mhz MOBO: MSI b350 tomahawk VGA: MSI Ventus 2X 4060TI 16GB ALI: Cooler Master V550 SSD: Samsung 970 Evo Plus Trattive+:(a) topolino2808(x2), galfum, giap959, sm_morgan, Biduzzo, huangwei, maxmax80, bubbi, dinamite2, PaxNoctis;(v) rubrie, CubeDs, Slater91, Juvanni, FireFox152, gluvocio, giulio81, emahwupgrade, Velvet, semmy83, giocher03 |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Prima di usare la rand() prova a chiamare la srand() in questo modo:
Codice:
srand ( time(NULL) ); Codice:
#include <time.h>
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jan 2010
Città: (MB)
Messaggi: 11971
|
Quote:
__________________
CPU: Ryzen 3700x DISSY: CM HYPER EVO 212 RAM: 16gb DDR4 3000Mhz MOBO: MSI b350 tomahawk VGA: MSI Ventus 2X 4060TI 16GB ALI: Cooler Master V550 SSD: Samsung 970 Evo Plus Trattive+:(a) topolino2808(x2), galfum, giap959, sm_morgan, Biduzzo, huangwei, maxmax80, bubbi, dinamite2, PaxNoctis;(v) rubrie, CubeDs, Slater91, Juvanni, FireFox152, gluvocio, giulio81, emahwupgrade, Velvet, semmy83, giocher03 |
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Anche questo è fattibile.
Se vuoi generare un numero casuale compreso tra 0 e 99 (per esempio) devi fare: Codice:
int num_casuale = rand() % 100;
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jan 2010
Città: (MB)
Messaggi: 11971
|
Quote:
__________________
CPU: Ryzen 3700x DISSY: CM HYPER EVO 212 RAM: 16gb DDR4 3000Mhz MOBO: MSI b350 tomahawk VGA: MSI Ventus 2X 4060TI 16GB ALI: Cooler Master V550 SSD: Samsung 970 Evo Plus Trattive+:(a) topolino2808(x2), galfum, giap959, sm_morgan, Biduzzo, huangwei, maxmax80, bubbi, dinamite2, PaxNoctis;(v) rubrie, CubeDs, Slater91, Juvanni, FireFox152, gluvocio, giulio81, emahwupgrade, Velvet, semmy83, giocher03 |
|
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Puoi postare il codice "incriminato"?
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield |
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Jul 2009
Città: Milano
Messaggi: 270
|
Scrivere rand() % 100 non ha alcun senso perchè rand() genera numeri reali compresi fra 0 e 1 e quindi il risultato di quell'espressione sarà sempre rand().
Se ho capito bene quello che vuoi fare (simulare il lancio di una moneta) puoi fare così: Codice:
u = rand(); if u <= 0.5 risultato = croce; else risultato = testa; Per quanto riguarda l'estrazione di numeri casuali da un intervallo ti invito a leggere questo breve post http://www.hwupgrade.it/forum/showthread.php?t=2435128
__________________
AMD PII x4 955 BE | Sapphire HD4850 Vapor-X 1 GB | Samsung SpinPoint F1 500GB | Samsung EcoGreen F4 2TB Gigabyte GA-MA790FXT-UD5P | Fractal Design Define R3 USB3.0 Titanium Grey | CORSAIR 650W CMPSU-650TX Noctua U12P SE2 | 2 x 2GB Kingston 1333 MHz | Samsung SyncMaster P2450 | Samsung SyncMaster T200 Ultima modifica di __ZERO_UNO__ : 14-01-2012 alle 13:56. |
|
|
|
|
|
#8 | |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Quote:
Infatti rand torna un int, mica un numero in virgola!
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield Ultima modifica di Mettiu_ : 14-01-2012 alle 14:03. |
|
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Jul 2009
Città: Milano
Messaggi: 270
|
Hai perfettamente ragione. Avevo dimenticato che si sta parlando di C.
Chiedo venia.
__________________
AMD PII x4 955 BE | Sapphire HD4850 Vapor-X 1 GB | Samsung SpinPoint F1 500GB | Samsung EcoGreen F4 2TB Gigabyte GA-MA790FXT-UD5P | Fractal Design Define R3 USB3.0 Titanium Grey | CORSAIR 650W CMPSU-650TX Noctua U12P SE2 | 2 x 2GB Kingston 1333 MHz | Samsung SyncMaster P2450 | Samsung SyncMaster T200 |
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Oct 2011
Messaggi: 48
|
rand viene sconsigliato nell'uso (chiaramente se si tratta del lancio della monetina va bene) ma se vuoi usare il programma per stimare la percentuale di volte che esce testa, e quella che esce croce su un numero di eventi molto grande e ottenere stime precise (che sarebbe una cosa stupida con la monetina visto che si sa che è del 50 %, ma interessante in un infinità di altri casi) conviene usare lrand48() si inizializza in questo modo:
Codice:
#include <stdlib.h>
#include <time.h>
int main() {
srand48(time(0)); // Inizializzazione del generatore di numeri casuali
.... codice ...
}
double FloatRandomNumber(double min, double max) {
return min + (max - min) * lrand48() / (double) RAND_MAX;
}
int IntRandomNumber(int min, int max) {
return min + lrand48() % (max - min + 1);
}
|
|
|
|
|
|
#11 | |
|
Member
Iscritto dal: Feb 2011
Messaggi: 46
|
Quote:
io nel man di lrand48 (che include anche drand48, erand48, lrand48, nrand48, mrand48, jrand48) leggo: These functions are declared obsolete by SVID 3, which states that rand(3) should be used instead. poi nel man di rand: The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3), so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed. (Use random(3) instead.) |
|
|
|
|
|
|
#12 | |
|
Member
Iscritto dal: Oct 2011
Messaggi: 48
|
In genere rand viene sconsigliata in genere perché in aclune vecchie implementazioni non ha una grande precisione. lrand48() e simili sono sconsigliate se devono essere all'interno di algoritmi di sicurezza, poiché sono facilmente violabili (da questo punto di vista penso siano obsolete). Nel manuale Practical UNIX & internet security ho trovato questo:
Quote:
__________________
Opok il nuovo gioco open source ispirato ai Pokemon (fatto da me ;-D) (http://sourceforge.net/projects/opok/):
|
|
|
|
|
|
|
#13 | |
|
Member
Iscritto dal: Feb 2011
Messaggi: 46
|
Quote:
|
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jan 2010
Città: (MB)
Messaggi: 11971
|
sinceramente non mi interessano molto ora gli algoritmi di sicurezza, più che altro, non mi viene ancora per bene il lancio della monetina :d
__________________
CPU: Ryzen 3700x DISSY: CM HYPER EVO 212 RAM: 16gb DDR4 3000Mhz MOBO: MSI b350 tomahawk VGA: MSI Ventus 2X 4060TI 16GB ALI: Cooler Master V550 SSD: Samsung 970 Evo Plus Trattive+:(a) topolino2808(x2), galfum, giap959, sm_morgan, Biduzzo, huangwei, maxmax80, bubbi, dinamite2, PaxNoctis;(v) rubrie, CubeDs, Slater91, Juvanni, FireFox152, gluvocio, giulio81, emahwupgrade, Velvet, semmy83, giocher03 |
|
|
|
|
|
#15 | |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Quote:
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[])
{
srand(time(0));
int numero_casuale = rand() % 2;
// numero_casuale vale 1 oppure 0
if(numero_casuale == 0)
printf("TESTA\n");
else
printf("CROCE\n");
system("PAUSE");
return 0;
}
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Se ripeti l'esecuzione velocemente viene sempre lo stesso risultato per un secondo, a causa di time che da un risultato in secondi: ipotizzo possa essere questo il problema...
Se si vogliono fare più estrazioni si devono fare in un ciclo dopo l'inizializzazione del seme random. Resta che se si rilancia il programma nello stesso secondo si otterranno gli stessi risultati, ma direi che è una pignoleria un po' esagerata per questo caso. Per completezza riporto anche un veloce esempio di aumento precisione temporale del seme iniziale (GNU/Linux \ BSD): Codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[])
{
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
srand(ts.tv_nsec); //Usando solo i nanosecondi della struttura è possibile
//che si reinizializzi il seme allo stesso valore
int numero_casuale = rand() % 2;
// numero_casuale vale 1 oppure 0
if(numero_casuale == 0)
printf("TESTA\n");
else
printf("CROCE\n");
return 0;
}
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Jan 2010
Città: (MB)
Messaggi: 11971
|
ma non si può fare un algoritmo che non dipenda dal tempo??
__________________
CPU: Ryzen 3700x DISSY: CM HYPER EVO 212 RAM: 16gb DDR4 3000Mhz MOBO: MSI b350 tomahawk VGA: MSI Ventus 2X 4060TI 16GB ALI: Cooler Master V550 SSD: Samsung 970 Evo Plus Trattive+:(a) topolino2808(x2), galfum, giap959, sm_morgan, Biduzzo, huangwei, maxmax80, bubbi, dinamite2, PaxNoctis;(v) rubrie, CubeDs, Slater91, Juvanni, FireFox152, gluvocio, giulio81, emahwupgrade, Velvet, semmy83, giocher03 |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Certo, basta trovare un'altro valore casuale che sia sempre diverso... ok, a quel punto non serve più rand.
Oppure un'altro valore che sia costantemente crescente; se non interessa la sicurezza potrebbe essere il numero assoluto di esecuzioni di quel programma (che occorrerebbe salvare da qualche parte). Il tempo ha la caratteristica di essere un valore monotono crescente, è quindi perfetto per inizializzare srand a valori sempre diversi, con due limiti:
Qui arrivano le mie conoscenze in materia, non escludo che mi sfugga qualcosa non essendomi mai interessato molto all'argomento.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
|
|
|
|
|
#19 |
|
Member
Iscritto dal: Jul 2011
Messaggi: 246
|
Anni fa lessi un libro in cui si parlava del cosiddetto "pool di entropia", ovvero di un pozzo che viene riempito dal SO (Linux in quel caso) con dati casuali provenienti da sorgenti di input (tastiera, mouse, interrupt)... Praticamente puoi attingere da questo pozzo per prelevare i bytes che ti servono. Non ho mai usato una cosa del genere ma se vuoi puoi approfondire cerca un pò in rete, partendo da wiki:
http://it.wikipedia.org/wiki//dev/random
__________________
Non c'è cosa peggiore nella vita di un programmatore di un errore che si presenta solo ogni tanto. CONCLUSO POSITIVAMENTE CON: oldfield |
|
|
|
|
|
#20 | |
|
Member
Iscritto dal: Feb 2011
Messaggi: 46
|
Quote:
Codice:
void seed_random(){
/* Lettura di un seed dal device random */
FILE* seme = fopen("/dev/random","r");
if(seme == NULL)
errore("Errore nella lettura del device urandom\n",1);
if(fread(&seed,3,1,seme) != 1)
errore("Errore nell'inizializzazione del seed\n",2);
fclose(seme);
}
oltre a /dev/random c'è anche /dev/urandom, che a differenza del primo non si esaurisce mai, ma come c'è scritto nel man: A read from the /dev/urandom device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:49.




















