WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   java - dummiefrage über Math.random() (http://www.wcm.at/forum/showthread.php?t=48364)

RaistlinMajere 03.03.2002 16:07

java - dummiefrage über Math.random()
 
nur rein interessehalber möchte ich folgendes wissen:

wenn ich eine zufallszahl (int) ausgeben möchte, die zwischen 0 und 15 sein soll, dann mache ich das so:

int zahl = (int) Math.random() * 15;
System.out.println(zahl);


eine andere möglichkeit wäre:

double zahl = Math.random() * 15;
System.out.println((int) zahl);


nur komischerweise, obwohl beides eigentlich dasselbe bewirken sollte, bringt mir ersteres eine ausgabe von 0 und nur zweiteres wirklich eine entsprechende zufallszahl.
kann mir jemand erklären, warum? :confused:

harakiri 03.03.2002 16:20

weil die funktion random() einen wert >= 0 und < 1 liefert und beim casting (typenumwandlung) auf (int) einfach die nachkommastelle abgeschnitten wird, und daher immer 0 rauskommen muss.

RaistlinMajere 03.03.2002 16:24

also wenn ichs so machen würde

int zahl = (int) (Math.random() * 15);

müßts dann wohl gehen, oder?

JosefS 03.03.2002 16:24

ganz einfach:
da Math.random() eine zahl zwischen 0 und 0.9999999 liefert und du mit

Code:

int zahl = (int) Math.random() * 15;
            ^ Zahl zwischen 0 und 0.99999 in int ist immer 0!

gleich das ergebnis von Math.rand() in int umwandelst, was natürlich immer 0 ist!

probier mal:
Code:

int zahl = (int) (Math.random() * 15);
dann gehts auch ;-)

achja: die zahl ist aber zwischen 0 und 14! ( "rand() * 16" liefert eine zahl zw 0 und 15)

Tarjan 03.03.2002 16:31

Zitat:

Original geschrieben von RaistlinMajere
also wenn ichs so machen würde

int zahl = (int) (Math.random() * 15);

müßts dann wohl gehen, oder?

Ja, hier wird zuerst multipliziert und dann erst gecastet. Ansonsten zuerst gecastet und dann erst multipliziert.

RaistlinMajere 03.03.2002 16:38

Zitat:

Original geschrieben von JosefS
achja: die zahl ist aber zwischen 0 und 14! ( "rand() * 16" liefert eine zahl zw 0 und 15)

mah, *bledbin* natürlich hast recht, vielen dank auch (an alle übrigens).

RaistlinMajere 03.03.2002 18:30

diese frage ist mir geradezu peinlich
 
aber ich hock jetzt schon viel zu lange an dem und soviel zeit hab ich heute einfach nicht, d.h. poste ichs trotzdem:
im darunterliegenden java-qt wird die whileschleife endlos ausgeführt, aber ich verstehe beim besten willen nicht, warum.
wäre super, wenn mir das jemand sagen könnte, fürs geübte auge isses sicher nur ein kurzer blick. das ganze dient dazu, um ein array mit 16 unterschiedlichen zufallszahlen von 0-15 zu füllen.


int[] array = new int[16];
int zz, vorhanden = 0;
boolean schonda = false;

while(vorhanden < 16) {
zz = (int) (Math.random() * 15);

for(int i=0; i<array.length; i++) {
if(array[i] == zz) {
schonda = true;
break;
}
}

if(schonda) {
schonda = false;
System.out.println(zz + " -> ist schon vorhanden");
}
else {
System.out.println(zz + " -> noch nicht vorhanden");
array[vorhanden] = zz;
vorhanden++;
}
}

JosefS 03.03.2002 18:43

probiers mal mit:

Code:

int[] array = new int[16];
int zz, vorhanden = 0;
boolean schonda = false;

while(vorhanden < array.length-1)
{
        zz = (int) (Math.random() * 15);

        for(int i=0; i<=vorhanden; i++)
        {
                if(array[i] == zz)
                {
                        schonda = true;
                        break;
                }
        }

        if(schonda)
        {
                System.out.println(zz + " -> ist schon vorhanden");
        }
        else
        {
                System.out.println(zz + " -> noch nicht vorhanden");
                array[vorhanden] = zz;
                vorhanden++;
        }

        schonda = false;
}


harakiri 03.03.2002 18:43

Re: diese frage ist mir geradezu peinlich
 
Zitat:

Original geschrieben von RaistlinMajere

while(vorhanden < 16) {
zz = (int) (Math.random() * 15);

for(int i=0; i<array.length; i++) {
if(array[i] == zz) {
schonda = true;
break;
}
}


imho hast du vergessen in der while-schleife den zähler "vorhanden" zu erhöhen, denn dein zu deinem statement "verhanden++" kommt das prog eben nie...

JosefS 03.03.2002 18:51

Re: Re: diese frage ist mir geradezu peinlich
 
Zitat:

Original geschrieben von harakiri


imho hast du vergessen in der while-schleife den zähler "vorhanden" zu erhöhen, denn dein zu deinem statement "verhanden++" kommt das prog eben nie...

hm....
der fehler liegt in folgendem:

while(vorhanden < 16) {
zz = (int) (Math.random() * 15);

"Math.random() * 15"
liefert zahlen von 0 bis 14, dh. 15 verschiedene zahlen->vorhanden kann niemals 16 erreichen, sondern nur 15

die schleife kann trotzdem recht lange dauern, da man bei schon 14 gezogenen zahlen, die 15. "zufällige" genau die übriggelassene sein muss, dh. im schnitt 15 durchläufe für die letzte+14 für die vorletzte usw...

RaistlinMajere 03.03.2002 19:18

@JosefS
 
vielen dank, deine tipps waren entscheidend:
erstens natürlich der fehler, daß ich nur zahlen von 0-14 generiert habe, jedoch von 0-15 abgefragt habe (soviel zur endlosschleife) und 2. noch

Code:

for(int i=0; i<vorhanden; i++)
macht natürlich mehr sinn, nicht grundsätzlich den gesamten arrayinhalt abzufragen, sondern nur jene felder, die bereits mit gewünschen werten belegt wurden, bringt viel performance.

obwohl diese nunmehr relativ flott läuft, fällt jemandem eine einfachere lösung ein, um ein array wie gewünscht mit randomwerten zu füllen?

vielen dank nochmal für alle antworten.

Sesa_Mina 03.03.2002 19:29

Ich schreib das hier mal als basic code her aber umsetzen sollt ja ganz ganz easy sein ;)
Code:

  dim array(15) as byte
  for x=0 to 15:array(x)=x:next
  for x=0 to 15
      y=int(rnd*16)
      z=int(rnd*16)
      a=array(y):array(y)=array(z):array(z)=a
  next

Damit hast mal ein geordnetes array in dem nachher 16 mal zwei der Werte vertauscht werden. Damit hast recht einfach und vor allem schnell ein durcheinandergewürfeltes array das nur gewünschte zahlen enthält und ausserdem keine doppelt. Somit sparst dir an haufen überprüfungen usw.

RaistlinMajere 03.03.2002 19:58

sorry
 
aber aus dem code werd ich nicht recht schlau, hatte nie was mit basic zu tun. :(

moorhahn 03.03.2002 20:03

zuerst wird das feld von 0 bis 15 angefüllt, in das feld 0 wird 0 geschrieben, in das 1. 1, ...... . dann werden die inhalte irgendwie durcheinandergewürfelt, aber es werden keine neuen zahlen mehr ins feld geschrieben.

RaistlinMajere 03.03.2002 20:07

das prinzip ist simpel und mir auch schon durch den kopf gegangen, nur hab ich keine ahnung, wie ich das durcheinanderwürfeln mit java anstelle.

moorhahn 03.03.2002 20:12

etwa so:
Code:

// zuerst das feld mit zahlen anfüllen

//durcheinanderwürfeln
int a,b,c
for (int i=0;i<15;i++) {
  a=(int)(Math.random()*16); 
  b=(int)(Math.random()*16); 

  // dreieckstausch
  c=feld(a);
  feld(a)=feld(b);
  feld(b)=c;
}


RaistlinMajere 03.03.2002 20:19

hmm
 
ok, das leuchtet ein, geht kein wert verloren und die werte werden zufällig miteinander vertauscht, umso mehr, je länger man die forschleife durchlaufen läßt.


Alle Zeitangaben in WEZ +2. Es ist jetzt 05:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag