» »

[C] random do poljubne številke

[C] random do poljubne številke

drejc ::

Imam en zlo simpl problem. Kako dobiti random stevilko na intervalu recimo 0-16 v gnu c?


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

#define RAND_MAX 16

int main() {
  srand (time (0)); 
  int num1 = rand();
  printf("random iz %d rand max is %d \n",num1,RAND_MAX);
}
 



Cifre so vedno večje od 16, čeprav je rand max spremenjen kot je navedeno v dokumentaciji. Če ne uporabim srand(time(0)) je output vedno 0.
"Rise above oneself and grasp the world"
- Archimedes of Syracuse

napsy ::

poskus tole.

int rand(int od, int _do)
{
return ((rand() / (double)do) + _od);
};
"If you die, you die. But when you live you live. There is no time to waste."

gumby ::

x=RAND_MAX/16;
y=rand()/x;

takole probaj


edit:
"#define RAND_MAX" brisi, to je ze v headerju doloceno, kot mora biti.
my brain hurts

Zgodovina sprememb…

  • spremenil: gumby ()

Alec999 ::

nevem sicer zakaj ne uporabis npr.
.
.
#define MOJ_MAX 16
.
.
int num1 = rand() % MOJ_MAX;

ampak OK. Mogoče bi ti ustrezala spodnja rešitev:
 
#include <stdlib.h>
#include <stdio.h>
#include <time.h>


#ifdef RAND_MAX
#undef RAND_MAX
#define RAND_MAX 16
#define rand() ( rand()%RAND_MAX )
#endif

int main() 
{
  
    srand (time (NULL));
    int num1 = rand();
  
    printf("random iz %d rand max is %d \n",num1, RAND_MAX);
  
    return 0;

}

BigWhale ::

man srand


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 follow-
ing comments are made:
"If you want to generate a random integer between 1 and 10, you
should always do it by using high-order 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 prac-
tical random-number generation issues in Chapter 7 (Random Numbers).



Vsega deset udarcev po tipkovnici...

Zgodovina sprememb…

  • spremenil: BigWhale ()

drejc ::

Ok tnx, sem potem tut sam pogledal man...silly me :).

Zanima me, kak zdej ta exe pripravim do tega da se bo lahko poganjal iz windows konzole. Namrec skompajlal sem zadevo znotraj cygwin okolja in se mi potem pritozuje da ne najde cygwin1.dll. Je mozno da zlinkam tale dll zraven v exe nekako?
"Rise above oneself and grasp the world"
- Archimedes of Syracuse

drejc ::

no, ce dodam -mno-cygwin flag v ccju sicer lahko poganjam v win cmd.exe, le random ni ravno random...spremeni se vsakih 10 sekund pa se to samo za +1.
"Rise above oneself and grasp the world"
- Archimedes of Syracuse

drejc ::

Taka je koda, output je ravnotako isti oz se poveca +1 na vsake par sekund tudi ce skompajlam z minGWjem.

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

int main(){
  int j;
  int k;
  srand(time(NULL));
  j = 1 + (int) (356.0 * (rand() / (RAND_MAX + 1.0)));
  k = (int) (357.0 * (rand() / (RAND_MAX + 1.0)));

  printf("nakljucna stevilka na intervalu 1 do 357 je %d \n",j);
  //printf("nakljucna stevilka na intervalu 0 do 357 je %d \n",k);
}
"Rise above oneself and grasp the world"
- Archimedes of Syracuse

Gundolf ::

Se kaksn rand() prej klic pa se bo spremenil. Tale srand in time ocitno nista najboljsa kombinacija na mingw-ju.

BigWhale ::

Ja, vsekakor je najbolje uporabiti /dev/urandom, ce je moznost.

drejc ::

En rand() prej klicu in zadeva gre skroz tudi pod cygwinom z -mno-cygwin flagi. :))

A je to kaksen poseben razlog zaka je treba random klicat dvaput?
"Rise above oneself and grasp the world"
- Archimedes of Syracuse

Gundolf ::

Očitno rand tako deluje, da najprej vzame seed in (pogojno) vrne rezultat, potem pa šele popravi seed, za naslednjo random številko. Ker je seed nastavljen na trenutni čas potem dobiš to, kar si ti dobil, da je prvi rand dokaj povezan z nastavitvijo seeda, se pravi s trenutnim časom. To bi lahko bil razlog, čeprav ne vem zakaj bi rand tako deloval.

BigWhale ::


capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 332
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 104
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 104
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 55
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 180
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 131
capybara code $ ./lala
nakljucna stevilka na intervalu 1 do 357 je 258
capybara code $


Na Linuxu dela povsem ok...

Ce pa kdaj vrne isto vrednost je pa to takrat, ko pozenes program v isti sekundi.

Must be a cygwin thing... Or windows

Gundolf ::

Ja definitivno se v winsih tko obnaša kot Drejc pravi. Lahko pa da je seveda to gcc 3.4.4 thing :)

'FireSTORM' ::

to je zaradi srand(time(NULL));
pognal programček 3x v sekundi:
fire@xendria:~/programing$ ./test
1182293401
fire@xendria:~/programing$ ./test
1182293401
fire@xendria:~/programing$ ./test
1182293401

pa koda:
int main()
{
  cout << time(NULL) << endl;
  return 0;
}


time jemle čas samo po sekundah, ne zavzema stotink itd. zato je tudi logično v enaki sekundi enak time, z srand pa "ustvariš" random pool
če bi v srand dal kakšno vrednost ki je v vsakršni stotinki različna bi blo že drugače...
Jaz sem to "rešil" tako da sem večkrat klical srand, prvič z time, potem sem zrandomiziral še eno cifro velikosti do 235446 in z tem še enkrat zagnal srand, torej:
srand(nova_randomized_stevilka);
Če že rabiš vsako stotinko drugo številko, jaz sem jo :P
Those penguins.... They sure aint normal....

Zgodovina sprememb…

napsy ::

seed problem pri rand() funkciji bi lahko rešil takole:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>


int main()
{
        struct timeval tv;
        gettimeofday(&tv, NULL);
        srand(tv.tv_sec + tv.tv_usec);

        printf("Random: %d\n", rand());

        return 0;
}


Ali pa bi uporabil kernel drajver za random števila kot je to že nekdo prej omenil:
#include <stdio.h>
#include <stdlib.h>

int main()
{
        FILE *rnd_f;
        int n;

        rnd_f = fopen("/dev/urandom", "rb");

        fread(&n, 1, sizeof(int), rnd_f);
        printf("Random: %d\n", n);

        fclose(rnd_f);
        return 0;
}
"If you die, you die. But when you live you live. There is no time to waste."

'FireSTORM' ::

Za /dev/urandom sem slišal da vendarle ni tako random...baje
kolko je resnice v tem nevem, ker nisem ravno šel raziskovat
Those penguins.... They sure aint normal....

napsy ::

Če /dev/urandom ne zadošča pa zato openssl knjižnica ponuja izvrstne algoritme za generacijo psevdo-random števil.

... en grdi hek
#include <stdio.h>
#include <stdlib.h>

#define RND_LEN sizeof(int)
int main()
{
        FILE *ssl_rnd;
        char cmd[64];
        int n;

        sprintf(cmd, "/usr/bin/openssl rand %d", RND_LEN);
        if ((ssl_rnd = popen(cmd, "r")) == NULL) {
                perror("Zagon openssl spodletel");
                exit(-1);
        }

        fread(&n, 1, RND_LEN, ssl_rnd);
        printf("Random stevilo: %d\n", n);

        pclose(ssl_rnd);
        return 0;
}
"If you die, you die. But when you live you live. There is no time to waste."

Zgodovina sprememb…

  • spremenil: napsy ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Vprašanje v zvezi z rand() funkcijo

Oddelek: Programiranje
494921 (4111) fireice
»

[C++] Generiranje naključnih števil tipa double

Oddelek: Programiranje
81751 (1660) mn
»

C++

Oddelek: Programiranje
121200 (936) BALAST
»

[C] Random funkcija

Oddelek: Programiranje
92221 (2052) primozsu
»

srand in program v Cju???

Oddelek: Programiranje
131522 (1392) nuclear

Več podobnih tem