# Verstehe ZufallInt = (int) (Math.random() * 5 + 1); nicht



## Berg (5. Jan 2013)

Liebe Forenmitglieder,
...wieder eine Verständnisfrage eines Anfängers, mit der Bitte um Hilfe...

Mein eigentliches Ziel war es einen Zufallszahl zwischen 0 und 6 zu generieren - einen Würfelersatz eben.
Zuerst habe ich die Randomzahl mit double deklariert und dann gemerkt, dass das mit dem Runden und dem Abschneiden auf eine Stelle gar nicht so einfach ist(für einen Anfänger).
bin ich 


```
package paket1;
import java.lang.Math;

public class Berg 
{
	public static void main(String[] args) 
	{
		double Zufallszahl_nackt, Zufallszahl, a, b, c;
		
			Zufallszahl_nackt = Math.random();
			Zufallszahl = (Zufallszahl_nackt * 5+1);
			
			a = Math.round(Zufallszahl);
			b = Math.floor(Zufallszahl);
			c = Math.ceil(Zufallszahl);
			
			System.out.println("Zufallszahl_nackt=  "+ Zufallszahl_nackt + " liefert eine zufällige Kommazahl zwischen 0 und 1");
			System.out.println("Zufallszahl=             "+ Zufallszahl + " mit ....*5+1 wird eine Kommazahl zwischen 1 und 6 daraus"); 
			System.out.println("Zahl mit round =      "+ a +" rundet ab dem Wert x,5 auf, sonst ab - 'schönes' mathematisches Runden - aber es bleibt eine Kommazahl mit x,0");
			System.out.println("Zahl mit floor =        "+ b +" liefert die nächst kleinere ganze Zahl, die kleiner oder gleich der Zahl ist");
			System.out.println("Zahl mit ceil =         "+ c + " liefert die nächst größere ganze Zahl\n");

//Ausagebbeispiel:
//Zufallszahl_nackt=  0.4657391783913212 liefert eine zufällige Kommazahl zwischen 0 und 1
//Zufallszahl=             3.328695891956606 mit ....*5+1 wird eine Kommazahl zwischen 1 und 6 daraus
//Zahl mit round =      3.0 rundet ab dem Wert x,5 auf, sonst ab - 'schönes' mathematisches Runden - aber es bleibt eine Kommazahl mit x,0
//Zahl mit floor =        3.0 liefert die nächst kleinere ganze Zahl, die kleiner oder gleich der Zahl ist
//Zahl mit ceil =         4.0 liefert die nächst größere ganze Zahl
```


Dann bin ich über folgende Lösung in einem Buch gestolpert.
Die funktioniert zwar hervorragend und macht genau das was ich will...
...ich verstehe aber leider die Syntax gar nicht...



```
// Will man eine ganze Zahl (z.B. wie von einem Würfel) dann empfiehlt sich folgende Vorgehensweise	
			
int ZufallInt;
ZufallInt = (int) (Math.random() * 5 + 1);
System.out.println("ZufallInt=                 "+ ZufallInt);
	}
}
```

>>> Könnt ihr mir bitte diese ersten zwei Zeilen erklären?
>>> Warum kann man denn den Code nicht wie folgt in zwei Zeilen aufteilen?


```
z = (int) (Math.random() * 5 + 1);
ZufallInt = (z);
```

>>> Wo in der Java API Docu findet man denn die Definition des Befehls (int) (...was immer das an der Stelle auch ist)?

Vielen Dank & viele Grüße
Berg


----------



## DrZoidberg (5. Jan 2013)

Das hier
(int)...
nennt sich "cast"
Typumwandlung ? Wikipedia
JAVA-Doku Casting
Die Zahl wird nach int gecastet. Dabei wird immer abgerundet.
Also

```
double a = 1.99;
int b = (int)a;
```
Ergibt 1 und nicht 2.

Math.random erzeugt einen double Wert zwischen 0 und 1, wobei aber niemals genau 1 rauskommt. Der Wert ist immer kleiner als 1. Also genau genommen erzeugt Math.random einen Wert zwischen 0 und 0.9999999999999999
Wenn du das jetzt mit 6 (nicht 5) multiplizierst und 1 addierst, erhältst du einen double Wert zwischen 1 und 6.999999999999999. Castest du das dann nach int wird abgerundet und du hast dann einen Wert zwischen 1 und 6.

```
int z = (int)(Math.random() * 6 + 1);
```


----------



## Phash (5. Jan 2013)

```
z = (int) (Math.random() * 5 + 1);
```

z = -> Zuweisung
(int) -> ein cast auf Int. Math.random() liefert ein double - der Cast auf einen Integerwert, schneidet in Java einfach alles nach dem Komma ab. Die Kommazahl wird durch abrunden auf eine Ganzzahl gebracht.

Math.random() -> ausfuehren der statischen Methode "random()" der Kasse Math.

*5 -> ergibt Zahlen, die zwischen 0 und 6 liegen

+1 -> ein Wuerfel hat ja keine 0, sondern eine 1 und er hoert bei 6 auf und nicht bei 5.
Da der Wertebereich der vorherigen Rechnung 0<x<6 ist, musst du ihn um eins erhoehen um Zahlen von 1-6 zu erhalten (durch Abrundung! das heisst auch 6.99 wird 6 und alles mit einer 0 vorne dran wuerde zur 0)


----------



## Pentalon (5. Jan 2013)

Hi Berg

Der Datentyp INT speichert nur den Wert VOR dem Komma.
Das ist bei 0.12345 exakt 0 
Wenn Du jetzt eine Zahl zwischen 1 und 5 haben möchtest multiplizierst Du die Zahl die Math.random dir zurückgibt mit 5.
Dann hast Du eine Fliesskommazahl zwischen 0 und 4.9999999. Du möchtest aber eine Zahl zwischen 1 und 5, also addierst Du noch eine 1 hinzu. Damit hast Du eine Fliesskommazahl zwischen 1 und 5.99999999, dass speicherst Du mit dem cast in Deine int   Variable:


```
ZufallInt = (int) (Math.random() * 5 + 1);
```

und Du hast eine Zahl zwischen 1 und 5.

Das (int) ist, wie oben schon gesagt wurde ein Cast (Umwandlung des Datentyps) die notwendig ist, da die Zahl von Math.random() eine Fliesskommazahl ist und Du sie in einem Int speichern möchtest.

Pentalon


----------



## hüteüberhüte (5. Jan 2013)

Boah Leute, das kann man ja nicht mit ansehen:


```
int z = (int) (Math.random() * 6.0) + 1;
```

Wisst ihr, dass double Addition eine sehr sehr ungenau Angelegenheit ist?


----------



## Berg (5. Jan 2013)

...danke an alle für die flotten und detaillierten Erklärungen !!!
...jetzt kann ich nicht nur casten...sondern weiß auch was es ist ;-)

...jetzt kam eben noch der Kommentar von hüteüberhüte rein...
...ist in diesem Beispiel (Zufallszahl) eine Rechenungenauigkeit relevant?
...gibt es hier einen Vorschlag der offensichtlich besser ist...und allen von euch, ausser mir, bekannt ist?

Vielen Dank & viele Grüße
Berg


----------



## DrZoidberg (5. Jan 2013)

Berg hat gesagt.:


> ...ist in diesem Beispiel (Zufallszahl) eine Rechenungenauigkeit relevant?


Eine Rechenungenauigkeit könnte dazu führen, dass manchmal eine 7 rauskommt obwohl es nie mehr als 6 
sein sollten.


> ...gibt es hier einen Vorschlag der offensichtlich besser ist...und allen von euch, ausser mir, bekannt ist?


Nun - wir wollten es ja eigentlich geheim halten aber ich verrats dir trotzdem.
Du kannst auch schreiben

```
import java.util.Random;
...
Random rand = new Random();
int z = rand.nextInt(6)+1;
```


----------



## Berg (5. Jan 2013)

Danke !!!!!


----------



## hüteüberhüte (5. Jan 2013)

... und dann daran denken, am besten während der gesamten Laufzeit nur eine Instanz von Random zu benutzen.  (Ich möchte auch ein Danke, mein Hinweis war nicht falsch, und hin und wieder Danke-Bettelei.  ) Grüße!


----------



## Berg (6. Jan 2013)

...definitiv gibt es hier auch ein DANKE!!! (sollte eigentlich schon geschehen sein...) 
Viele Grüße
Berg


----------

