Dies scheint ein wirklich seltsames Problem zu sein:
Das ist mein Code:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
srand((unsigned int)time(NULL));
int newRandomNumber = 0;
newRandomNumber = rand() % 7;
NSLog(@"%d", rand() % 7); //This prints out what I expected
NSLog(@"newRandomNumber = %d", newRandomNumber); // This always prints out 0!
}
return 0;
}
Wenn ich diese eine Zeile ersetze, die besagt
newRandomNumber = rand() % 7
mit
newRandomNumber = rand() % 8
alles funktioniert einwandfrei. Warum ist das so?
Kann dein Problem in nicht reproduzieren C.
– Matte
23. Oktober 2011 um 14:42 Uhr
Ich kann dies in Objective-C reproduzieren. Sogar mit srand([[NSDate date] timeIntervalSince1970]). Aber Übergabe kleinerer Ganzzahlen an srand() scheint es zu beheben.
– Lukman
23. Oktober 2011 um 14:47 Uhr
Was erhalten Sie, wenn Sie rand() drucken? Erhalten Sie jedes Mal die gleiche Zahl oder nur etwas, das zu 0 modulo 7 kongruent ist?
– Omri Barel
23. Oktober 2011 um 14:48 Uhr
Hast du mehr als einmal versucht zu iterieren? Ich vermute, dass der erste Wert von rand() immer ein Vielfaches von 7 ist.
– Heiße Licks
17. November 2013 um 15:44 Uhr
verwandt: Rand() % 14 erzeugt nur die Werte 6 oder 13
Wikipedia-Artikel Linearer Kongruenzgenerator bestätigt, dass CarbonLib tatsächlich Xn+1 = Xn * 16807 verwendet, um Zufallszahlen zu generieren.
Formel unter Linux 2.6.32, die ich ausführe, ist komplizierter. Es hat die Form next = ( next * const_1 + const_2) % 32.768. Offensichtlich haben Sie die Formel Ihrer Plattform möglicherweise rückentwickelt. Es ist jedoch implementierungsabhängig mit Konstanten, die nach dem Drehen und Wenden oft nahezu Primzahlen sind.
– Gnometorule
23. Oktober 2011 um 18:12 Uhr
Es ist jedoch unwahrscheinlich, sie zuerst einfach zu Resten ohne andere Transformationen zu machen.
– Gnometorule
23. Oktober 2011 um 18:13 Uhr
Was für eine schlechte Wahl von LCG
– phuklv
18. April 2015 um 9:00 Uhr
Der Teil, den Sie ausgelassen haben: seit 16807 % 7 == 0, (n * 16807) % 7 == 0 auch, solange Sie keinen Integer-Überlauf bekommen haben.
– Markieren Sie Lösegeld
24. September 2015 um 18:49 Uhr
Grady-Spieler
Es scheint unwahrscheinlich, aber bei einigen Tests scheint der erste Rand nach einem Srand immer durch 7 teilbar zu sein, zumindest in einer Variable mit Int-Größe.
Bei mehreren Läufen erhielt ich 1303562743, 2119476443 und 2120232758, die alle 7 auf 0 modden.
Der Zweite rand() funktioniert, weil es das zweite ist rand(). Werfen Sie einen rand() vor deinem ersten rand()… oder noch besser, verwenden Sie einen besseren Zufallszahlengenerator random oder arc4rand wenn verfügbar.
Siehe auch Stack Overflow-Frage Warum ist (rand() % irgendetwas) in C++ immer 0?.
Grady Player beantwortet Ihre Frage ziemlich genau: Dies liegt daran, dass es sich um Ihren ersten Anruf bei einer nicht wirklich zufällig generierten Nummer handelt. Aber noch ein Punkt und eine Tatsache, die mich immer noch verwirrt:
– Gnometorule
23. Oktober 2011 um 16:19 Uhr
(1) Wenn Sie mit stand() überhaupt nichts sehen, wird das System beim ersten Aufruf immer die vernünftige Nummer erzeugen. Auf meinem System verfolgt eine ‘next’-Variable den nächsten rand()-Wert, und next wird auf 1 gesetzt, wenn kein srand()-Aufruf erfolgt. Der zurückgemeldete Wert ist nach dem Addieren und Multiplizieren von Systemkonstanten und dem Ergebnis mod 32.768. Das bedeutet, dass Sie für einen bestimmten Modulus-Benutzer, der beim ersten Anruf ausgewählt wurde, immer noch 0 erhalten würden, in Ihrem Fall 7, aber es könnte eine andere Nummer sein.
– Gnometorule
23. Oktober 2011 um 16:23 Uhr
(2) Der Artikel spricht über Portabilitätsprobleme, die durch die Verwendung eines Moduls nicht beeinträchtigt würden. Im Wesentlichen weist es darauf hin, dass time_t möglicherweise nicht richtig in ein unsigned int umgewandelt werden kann; und dass es besser ist, mod nicht zu verwenden, sondern zu multiplizieren, um den gewünschten Bereich zu erhalten (in Ihrem Fall *7/RAND_MAX). Als dieses objektive C, das ich nicht kenne, könnte es ein Problem sein, aber ich bezweifle es. Was mich verwirrt, ist, dass der zurückgemeldete time()-Wert intern bei jedem globalen Timer-Interrupt in update_tines() (auf jeden Fall auf dem LINUX 2.6.xx-Kernel) aktualisiert wird, und dies sollte weit zwischen Sekunden-Ticks geschehen.
– Gnometorule
23. Oktober 2011 um 16:29 Uhr
Warum srand() zurückmelden würde, wie Sie es sagen, was im Wesentlichen 7-Sekunden-Schritte ausmacht (ich weiß, dass dies nicht genau das bedeutet, aber es scheint verwandt zu sein), lässt mich am Kopf kratzen.
– Gnometorule
23. Oktober 2011 um 16:30 Uhr
13949500cookie-checkWarum gibt rand() % 7 immer 0 zurück?yes
Kann dein Problem in nicht reproduzieren
C
.– Matte
23. Oktober 2011 um 14:42 Uhr
Ich kann dies in Objective-C reproduzieren. Sogar mit
srand([[NSDate date] timeIntervalSince1970])
. Aber Übergabe kleinerer Ganzzahlen ansrand()
scheint es zu beheben.– Lukman
23. Oktober 2011 um 14:47 Uhr
Was erhalten Sie, wenn Sie rand() drucken? Erhalten Sie jedes Mal die gleiche Zahl oder nur etwas, das zu 0 modulo 7 kongruent ist?
– Omri Barel
23. Oktober 2011 um 14:48 Uhr
Hast du mehr als einmal versucht zu iterieren? Ich vermute, dass der erste Wert von rand() immer ein Vielfaches von 7 ist.
– Heiße Licks
17. November 2013 um 15:44 Uhr
verwandt: Rand() % 14 erzeugt nur die Werte 6 oder 13
– phuklv
7. August 2018 um 8:03 Uhr