random liefert ungültige Werte (ausserhalb bereich)

Gast #4591456
Lesenswert?

hallo, ich möchte mit rand() zufallswerte in einem bereich erstellen, 
allerdings liefert mir die Funktion auch werte ausserhalb des bereichs
1
#include <iostream>
2
#include <stdlib.h>
3
#include <time.h>
4

5
int main(void){
6
...
7
  time_t t;
8
  time(&t);
9

10
  srand((unsigned int)t);
11
...
12
  n_guess = rand() % 20 + 10;
13
...
14
}


n_guess liefert auch werte über 20.


eigentlich ja auch richtig, wenn ich das richtig verstanden habe
n_guess = rand() % 20 liefert eine Zufallszahl zwischen 0 und 20. wenn 
ich dann noch 10 dazu addiere, kann es sein, dass ich über 20 komme.

setze ich die 20 + 10  in klammern, kämen ja werte zwischen 0 und 30 
heraus. Aber in allen beispielen die ich gesehen habe, ist das so 
geschrieben.
#4591471
Lesenswert?

Hallo,

Du hast vergessen, Deinen gewünschten Beeich anzugeben...

%20 ist eine Modulo-Division und leifert somit den Rest.
Bei Divison durch 20 kann der Rest also zwischen 0 und 19 liegen.
Wenn Du dann 10 addierst bist Du im Bereich 10...29.

Wenn Du 10...19 haben willst, solltest Du eben %10 (liefert 0...9) + 10 
rechnen (10...19).

Gruß aus Berlin
Michael
Gast #4591474
Lesenswert?

Es ist einfach die Schreibweise, die mich durcheinander bringt, da 'ich' 
die grenzen so nicht sofort erkenne.
wenn ich jetzt mit variablen arbeiten möchte
upper_bound = 20
lower_bound = 10
und ich möchte eine Zahl zwischen den Zahlen (also von 11 bis 19) muss 
ich ja schreiben
1
n_guess = rand() % (upper_bound - lower_bound - 1) + (lower_bound + 1);
#4591730
Lesenswert?

Mark schrieb:
> n_guess = rand() % 20 + 10;
> ...
> }
>
> n_guess liefert auch werte über 20.
>
> eigentlich ja auch richtig, wenn ich das richtig verstanden habe
> n_guess = rand() % 20 liefert eine Zufallszahl zwischen 0 und 20.

rand() liefert eine Zufallszahl im Bereich 0 bis RAND_MAX. Alles andere 
sind einfach arithmetische Berechnungen.

Mark schrieb:
> Es ist einfach die Schreibweise, die mich durcheinander bringt, da 'ich'
> die grenzen so nicht sofort erkenne.

Du gibst mit
1
  n_guess = rand() % 20 + 10;
ja auch keine Grenzen für rand() an, sondern führst einfach noch zwei 
Berechnungen mit dem Ergebnis durch. a % b liefert den Modulo, also den 
Rest der Ganzzahldivision aus a und b, und das + ist einfach nur eine 
gewöhnliche Addition.
Gast #4591775
Lesenswert?

Schreibe dir doch einfache eine Funktion, der du die obere und untere 
Grenze übergeben kannst und die diese kleine Berechnung ausführt. Die 
Funktion rufst du dann mit irgendwas_rand(11, 19) oder was auch immer 
auf und siehst sofort, was los ist.
Gast #4591813
Lesenswert?

Da du ja C++ verwendest, kannst du die C++ Random Funktionen nutzen, 
anstelle der alten C-Funktionen. Diese bieten u.a. eine einfachere 
Einstellung des Bereichs:
1
#include <iostream>
2
#include <random>
3

4
int main() {
5
  std::mt19937 gen;
6
  std::uniform_int_distribution<int> dist (10, 20);
7
  
8
  for (int i = 0; i < 100; ++i) {
9
    std::cout << dist (gen) << std::endl;
10
  }
11
  
12
  return 0;
13
}

Dies hat gegenüber der Version mit rand() und % den großen Vorteil, dass 
die Werte gleichverteilt sind, d.h. die Wahrscheinlichkeit dass 10 
auftritt ist gleich der Wahrscheinlichkeit dass 11 auftritt ... usw. Das 
ist bei "rand () % X" nur der Fall, wenn "X % RAND_MAX" gleich 0 ist.

Sieh z.B.
http://en.cppreference.com/w/cpp/numeric/random
http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
#4593062
Lesenswert?

Dr. Sommer schrieb:
> Werte gleichverteilt... Das ist bei "rand () % X" nur der Fall,
> wenn "X % RAND_MAX" gleich 0 ist.

> Äh, vertan. Es muss "RAND_MAX % X == X-1" sein

Stimmt! Ersteres ist falsch. Letzteres ebenso. Denn RAND_MAX ist die 
größte Zufallszahl, die rand() liefern kann (und tatsächlich öfter mal 
zurückgibt). Obergrenze für rand() ist RAND_MAX+1, das ist auch die 
Anzahl Werte einschl. Null, die rand() liefern kann. X ist die Anzahl 
der Werte im gewünschten Zahlenbereich von Null bis X-1. X ist die 
Obergrenze des Bereiches. Die Obergrenzen RAND_MAX+1 und X werden selbst 
nie erreicht. Die Zufallszahlen im gewünschten Bereich sind gleichmäßig 
verteilt, wenn (RAND_MAX+1) % X == 0 ist und rand() bei wiederholten 
Aufrufen auch tatsächlich gleichmäßig verteilte Werte liefert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren