Generieren von Zufallszahlen in Objective-C

Ich bin hauptsächlich ein Java-Kopf, und ich möchte eine Möglichkeit, eine Pseudozufallszahl zwischen 0 und 74 zu generieren. In Java würde ich die Methode verwenden:

Random.nextInt(74) 

Ich bin nicht an einer Diskussion über Samen oder echte Zufälligkeit interessiert, sondern daran, wie Sie die gleiche Aufgabe in Objective-C erfüllen. Ich habe Google durchforstet, und es scheint nur eine Menge verschiedener und widersprüchlicher Informationen zu geben.

Sie sollten die function arc4random_uniform () verwenden. Es verwendet einen höheren Algorithmus als rand. Sie müssen nicht einmal einen Samen setzen.

 #include  // ... // ... int r = arc4random_uniform(74); 

Die arc4random man-Seite:

 NAME arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include  u_int32_t arc4random(void); void arc4random_stir(void); void arc4random_addrandom(unsigned char *dat, int datlen); DESCRIPTION The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo- random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and random(3). The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom(). There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself. EXAMPLES The following produces a drop-in replacement for the traditional rand() and random() functions using arc4random(): #define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1)) 

Verwenden Sie die function arc4random_uniform(upper_bound) , um eine Zufallszahl innerhalb eines Bereichs zu generieren. Im Folgenden wird eine Zahl zwischen 0 und 73 einschließlich generiert.

 arc4random_uniform(74) 

arc4random_uniform(upper_bound) vermeidet Modulo-Bias wie auf der man-Seite beschrieben:

arc4random_uniform () gibt eine gleichmäßig verteilte Zufallszahl zurück, die kleiner als outer_bound ist. arc4random_uniform () wird über Konstruktionen wie “arc4random ()% outer_bound” empfohlen, da es ” modulo bias ” vermeidet, wenn die obere Grenze keine Zweierpotenz ist.

Genau wie C, würden Sie tun

 #include  

(Angenommen, Sie wollten 0, aber nicht 74, was Ihr Java-Beispiel tut)

Bearbeiten: Fühlen Sie sich frei, random() oder arc4random() für rand() arc4random() was, wie andere gezeigt haben, ziemlich sucky).

Ich dachte, ich könnte eine Methode hinzufügen, die ich in vielen Projekten verwende.

 - (NSInteger)randomValueBetween:(NSInteger)min and:(NSInteger)max { return (NSInteger)(min + arc4random_uniform(max - min + 1)); } 

Wenn ich es in vielen Dateien benutze, deklariere ich normalerweise ein Makro als

 #define RAND_FROM_TO(min, max) (min + arc4random_uniform(max - min + 1)) 

Z.B

 NSInteger myInteger = RAND_FROM_TO(0, 74) // 0, 1, 2,..., 73, 74 

Hinweis: Nur für iOS 4.3 / OS X 10.7 (Lion) und höher

Dies wird Ihnen eine Gleitkommazahl zwischen 0 und 47 geben

 float low_bound = 0; float high_bound = 47; float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound); 

Oder einfach nur

 float rndValue = (((float)arc4random()/0x100000000)*47); 

Sowohl die untere als auch die obere Grenze können ebenfalls negativ sein . Der folgende Beispielcode gibt Ihnen eine zufällige Zahl zwischen -35.76 und +12.09

 float low_bound = -35.76; float high_bound = 12.09; float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound); 

Konvertieren von Ergebnis in einen runder Ganzzahlwert :

 int intRndValue = (int)(rndValue + 0.5); 

Laut der Handbuchseite für rand (3) wurde die rand-Familie von functionen durch Zufall veraltet (3). Dies liegt an der Tatsache, dass die unteren 12 Bits von rand () ein zyklisches Muster durchlaufen. Um eine Zufallszahl zu erhalten, sättigen Sie einfach den Generator, indem Sie srandom () mit einem unsignierten Seed aufrufen, und rufen Sie dann random () auf. Also, das Äquivalent des obigen Codes wäre

 #import  #import  

Sie müssen srandom () nur einmal in Ihrem Programm aufrufen, es sei denn, Sie möchten Ihren Seed ändern. Obwohl Sie sagten, dass Sie keine Diskussion über wirklich zufällige Werte wünschen, ist rand () ein ziemlich schlechter Zufallszahlengenerator, und random () leidet immer noch unter Modulo-Bias, da er eine Zahl zwischen 0 und RAND_MAX erzeugt. Wenn RAND_MAX beispielsweise 3 ist und Sie eine Zufallszahl zwischen 0 und 2 haben möchten, erhalten Sie doppelt so wahrscheinlich eine 0 als eine 1 oder 2.

Besser, arc4random_uniform zu verwenden. Dies ist jedoch unter iOS 4.3 nicht verfügbar. Glücklicherweise bindet iOS dieses Symbol zur Laufzeit, nicht zur Kompilierzeit (also nicht die Präprozessor-Direktive #if verwenden, um zu prüfen, ob es verfügbar ist).

Die beste Methode, um festzustellen, ob arc4random_uniform verfügbar ist, besteht darin, arc4random_uniform zu tun:

 #include  int r = 0; if (arc4random_uniform != NULL) r = arc4random_uniform (74); else r = (arc4random() % 74); 

Ich habe meine eigene Zufallszahlen-Dienstprogramm-class geschrieben, so dass ich etwas hätte, das in Java etwas mehr wie Math.random () funktioniert. Es hat nur zwei functionen und es ist alles in C gemacht.

Header-Datei:

 //Random.h void initRandomSeed(long firstSeed); float nextRandomFloat(); 

Implementierungsdatei:

 //Random.m static unsigned long seed; void initRandomSeed(long firstSeed) { seed = firstSeed; } float nextRandomFloat() { return (((seed= 1664525*seed + 1013904223)>>16) / (float)0x10000); } 

Es ist eine ziemlich klassische Art Pseudo-Randoms zu erzeugen. In meinem App-Delegat rufe ich an:

 #import "Random.h" - (void)applicationDidFinishLaunching:(UIApplication *)application { initRandomSeed( (long) [[NSDate date] timeIntervalSince1970] ); //Do other initialization junk. } 

Dann sage ich später:

 float myRandomNumber = nextRandomFloat() * 74; 

Beachten Sie, dass diese Methode eine Zufallszahl zwischen 0.0f (inklusive) und 1.0f (exklusiv) zurückgibt.

Es gibt bereits einige großartige, klare Antworten, aber die Frage fragt nach einer zufälligen Zahl zwischen 0 und 74. Verwenden Sie:

arc4random_uniform(75)

Zufallszahl zwischen 0 und 99 generieren:

 int x = arc4random()%100; 

Generiere Zufallszahl zwischen 500 und 1000:

 int x = (arc4random()%501) + 500; 

// Im folgenden Beispiel wird eine Zahl zwischen 0 und 73 generiert.

 int value; value = (arc4random() % 74); NSLog(@"random number: %i ", value); //In order to generate 1 to 73, do the following: int value1; value1 = (arc4random() % 73) + 1; NSLog(@"random number step 2: %i ", value1); 

Ausgabe:

  • Zufallszahl: 72

  • Zufallszahl Schritt 2: 52

Ab iOS 9 und OS X 10.11 können Sie die neuen GameplayKit-classn verwenden, um Zufallszahlen auf verschiedene Arten zu generieren.

Sie haben vier Quellentypen zur Auswahl: eine allgemeine Zufallsquelle (unbenannt, bis auf das System, um auszuwählen, was sie tut), lineares Kongruenz, ARC4 und Mersenne Twister. Diese können zufällige Ints, Floats und Bools erzeugen.

Auf der einfachsten Ebene können Sie eine Zufallszahl aus der im System eingebauten Zufallsquelle wie folgt generieren:

 NSInteger rand = [[GKRandomSource sharedRandom] nextInt]; 

Das erzeugt eine Zahl zwischen -2.147.483.648 und 2.147.483.647. Wenn Sie eine Zahl zwischen 0 und einer oberen Grenze (exklusiv) möchten, verwenden Sie Folgendes:

 NSInteger rand6 = [[GKRandomSource sharedRandom] nextIntWithUpperBound:6]; 

GameplayKit hat einige Convenience-Konstruktoren eingebaut, um mit Würfeln zu arbeiten. Zum Beispiel können Sie einen sechsseitigen Würfel wie folgt rollen:

 GKRandomDistribution *d6 = [GKRandomDistribution d6]; [d6 nextInt]; 

Außerdem können Sie die Zufallsverteilung mit Dingen wie GKShuffledDistribution .

Für Spielentwickler benutze random (), um Randoms zu generieren. Wahrscheinlich mindestens 5x schneller als arc4random (). Modulo-Bias ist insbesondere bei Spielen kein Problem, wenn Zufallszahlen unter Verwendung des gesamten Bereichs von Zufallszahlen () erzeugt werden. Achten Sie darauf, zuerst zu säen. Rufen Sie srandomdev () in AppDelegate auf. Hier sind einige Hilfsfunktionen:

 static inline int random_range(int low, int high){ return (random()%(high-low+1))+low;} static inline CGFloat frandom(){ return (CGFloat)random()/UINT32_C(0x7FFFFFFF);} static inline CGFloat frandom_range(CGFloat low, CGFloat high){ return (high-low)*frandom()+low;}