• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

C# Zufallswerte in Instanz funktionieren nicht

Mr Speicher

Neu angemeldet

Registriert
22 Dez. 2013
Beiträge
83
Hallo, ich habe ein kleines Programm geschrieben mit dem per Zufall der Geburtstag erstellt wird sprich Tag, Monat, Jahr. Diese Methode befindet sich in einer eigenen Klasse und ich greife in Program über eine Instanz auf die Methode zu.
Mit einer While-Schleife lässt sich festlegen wie viele Zufallswerte generiert und ausgegeben werden sollen.
Das Problem ist aber, dass die Zufallswerte über die Instanz nicht richtig funktionieren, es kommen fast immer die selben Werte dabei heraus.

Hier ein Beispiel bei 20 Zufallsdurchgängen:
durchgänge.PNG

Müsste für jeden Durchgang nun eine neue Instanz erstellt werden damit es mit den Zufallszahlen klappt oder liegt der Fehler noch woanders ?

Hier ist mal der Code:
Program.cs
[src=csharp]namespace Test_2
{
class Program
{
static void Main(string[] args)
{
int anzahlDurchGaenge, hochZaehlen=0;

Console.Write("Anzahl Durchgänge eingeben: ");
anzahlDurchGaenge = Convert.ToInt32(Console.ReadLine());

Class1 aufruf = new Class1();

while (anzahlDurchGaenge >=hochZaehlen)
{
aufruf.zufallsWertGeburtstag();

hochZaehlen++;
}

Console.ReadLine();
}
}
}[/src]

Class1.cs
[src=csharp]namespace Test_2
{
class Class1
{
int tag, monat, jahr, personenAlter;

public void zufallsWertGeburtstag()
{

Random roundGB = new Random();

const int MONATALTERSBBERECHNUNG = 8, JAHRALTERSBERECHNUNG = 2015;

// Berechnungsteil für Monat, Tag und Jahr des Geburtstages
monat = roundGB.Next(1, 13);
if (monat == 2)
{
tag = roundGB.Next(1, 29);
}
else
{
tag = roundGB.Next(1, 31);
}

// Jahr berechnet mit Zufallswerten zw. 1950 und 1996
jahr = roundGB.Next(1950, 1997);

// Berechnet das Alter der Person
if (monat > MONATALTERSBBERECHNUNG)
{
personenAlter = JAHRALTERSBERECHNUNG - (jahr - 1);
}
else
{
personenAlter = JAHRALTERSBERECHNUNG - jahr;
}

Console.WriteLine(tag + "." + monat + "." + jahr + " " + personenAlter + " Jahre" + "\n");
}
}
}[/src]
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
statt random, was mit dem gleichen parameter, also in dem Fall keinem, immer die gleiche Abfolge liefert :

[src=csharp]public static int GenerateRandomNumber(int min, int max)
{
var c = new RNGCryptoServiceProvider();
// Ein integer benötigt 4 Byte
var randomNumber = new byte[4];
// Auffüllen mit einer kryptographisch starken Folge an zufälligen Werten
c.GetBytes(randomNumber);
// Umwandlung Byte-Array in Integer
int result = Math.Abs(BitConverter.ToInt32(randomNumber, 0));
// Setzen der inklusiven Grenzen
return result%max + min;
}[/src]
 

Timon3

Team ModMii

Registriert
17 Juli 2013
Beiträge
499
Um KaPiTN's Lösung mal zu erklären: Zufallszahlen sind am PC auch nicht wirklich zufällig, das geht nicht. Deshalb nimmt man einen bestimmten Seed, aus dem dann mittels mathematischen Verfahren Zahlen gewonnen werden, die zufällig erscheinen. Der Seed ist in den meisten Fällen zeitabhängig, weshalb hier KaPiTN nicht ganz Recht hat (http://referencesource.microsoft.com/#mscorlib/system/random.cs, Zeile 53). Da deine Instanzen im gleichen Tick erstellt werden, haben sie den gleichen Seed und geben die gleichen Werte. Die im obigen Beispiel genutzte Klasse umgeht das Problem, da sie die Zufallswerte nicht zeitabhängig generiert.
 

Mr Speicher

Neu angemeldet

Registriert
22 Dez. 2013
Beiträge
83
  • Thread Starter Thread Starter
  • #4
Ok, Danke für eure Ausführungen, wieder etwas gelernt.
Ich hatte gehofft es ginge so einfach über Random, jetzt werde ich mal die Lösung von KaPiTN zu implementieren.
 

Timon3

Team ModMii

Registriert
17 Juli 2013
Beiträge
499
Ist halt ein relativ unglücklicher Fehler. Du könntest aber einfach den Thread schlafen lassen, da die Random-Klasse den Environment-Tick-Count als Seed verwendet sollte das dir dann zufälliger wirkende Zahlen liefern.

https://msdn.microsoft.com/de-de/library/d00bd51t(v=vs.110).aspx

Ich schätze, 20 Millisekunden könnten reichen (die Auflösung des Zeitgebers scheint für gewöhnlich von 10 bis 16 Millisekunden zu variieren (Link)). Einfach an den Anfang oder das Ende deiner Zufallsmethode packen und mal testen.

Die tatsächliche Lösung für dein Problem ist aber ganz anders: Erstell nicht immer ein neues Random-Objekt. Das ist sehr unsauber. Du kannst es entweder als statisches Klassenattribut deklarieren, oder (was vermutlich die sinnvollste Lösung ist) von der separaten Klasse wegkommen und stattdessen das Random-Objekt als Attribut der Main-Klasse deklarieren. Dann kannst du auch die Funktion in die Main-Klasse packen.

Bei weiteren Fragen einfach Fragen :T
 
Oben