Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Satunnaislukujen generointi C++:ssa?

17 views
Skip to first unread message

Markus Luoma

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
Aloitin hiljattain C++:n opettelun. Teen parhaillaan
ohjelmaa, jossa tarvitaan satunnaisia luonnollisia lukuja
ykkösestä ylöspäin.

Sitä varten olen tehnyt funktion, joka saa syötteenään
suurimman halutun luvun (max_arvo) ja funktio generoi
luvun rivillä

double satunnaisluku = max_arvo * rand() / RAND_MAX; // rivi 1
int tulos = satunnailuku + 1; // rivi 2

Funktion vikana on se, että kun rand() = RAND_MAX tulostaa
arvon max_arvo + 1. Tämä tosin tapahtuu hyvin harvoin. Jos korvaan
funktion rivillä 1 olevan rand():in (rand() - 1):llä tai RAND_MAX:in
(RAND_MAX + 1):llä, aiheutuu satunnaislukuihin pientä vääristymää.
Mikä olisi elegantti tapa kiertää ongelma?

-Markus Luoma


Markus Luoma

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to

Kalle Olavi Niemitalo

unread,
Mar 16, 1999, 3:00:00 AM3/16/99
to
Hmm, tästä tuli nyt kyllä C:tä eikä C++:aa, mutta...

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

/* Palauttaa satunnaisluvun väliltä 0 .. OSIA-1. */
int
satunnaisluku(int osia)
{
/* Jotta kaikki satunnaisluvut olisivat yhtä yleisiä, jaetaan
rand():n paluuarvojen alue RAJA yhtä suureen osaan. Jos jako ei
mene tasan, alueen loppuosa hylätään.

Tässä laskussa pitäisi oikeastaan olla RAND_MAX+1, mutta siitä
voisi tulla inhottavia ylivuotoja. */
int osan_koko = RAND_MAX / osia;
int rnd;
do {
rnd = rand();
} while (rnd >= osia * osan_koko);
return rnd / osan_koko;
}

#define LUKUJA 10

int
main(void)
{
unsigned long kerrat[LUKUJA], l;
int i;
for (i = 0; i < LUKUJA; i++)
kerrat[i] = 0;
for (l = 0; l < 1000000; l++)
kerrat[satunnaisluku(LUKUJA)]++;
for (i = 0; i < LUKUJA; i++)
printf("%lu ", kerrat[i]);
printf("\n");
return 0;
}

Nieminen Mika

unread,
Mar 16, 1999, 3:00:00 AM3/16/99
to
Markus Luoma <markus...@edu.hel.fi> wrote:
: double satunnaisluku = max_arvo * rand() / RAND_MAX; // rivi 1

: int tulos = satunnailuku + 1; // rivi 2

: Funktion vikana on se, että kun rand() = RAND_MAX tulostaa
: arvon max_arvo + 1. Tämä tosin tapahtuu hyvin harvoin. Jos korvaan
: funktion rivillä 1 olevan rand():in (rand() - 1):llä tai RAND_MAX:in
: (RAND_MAX + 1):llä, aiheutuu satunnaislukuihin pientä vääristymää.
: Mikä olisi elegantti tapa kiertää ongelma?

Eikö (max_arvo-1) * rand() / RAND_MAX; toimi?

--
main(i,_){for(_?--i,main(i+2,"FhhQHFIJD|FQTITFN]zRFHhhTBFHhhTBFysdB"[i]
):5;i&&_>1;printf("%s",_-70?_&1?"[]":" ":(_=0,"\n")),_/=2);} /*- Warp -*/

0 new messages