Produire des nombres aléatoires dans L'objectif C

je suis un chef Java principalement, et je veux un moyen de générer un nombre pseudo-aléatoire entre 0 et 74. En Java, j'utiliserais la méthode:

Random.nextInt(74)

Je ne suis pas intéressé par une discussion sur les semences ou le vrai hasard, juste comment vous accomplissez la même tâche dans Objective-C. J'ai parcouru Google, et il semble juste qu'il y ait beaucoup de différents et contradictoires bits d'information.

716
demandé sur Peter Mortensen 2008-10-02 08:35:21

13 réponses

vous devez utiliser la fonction arc4random_uniform (). Il utilise un algorithme supérieur à rand. Vous n'avez même pas besoin de mettre une graine.

#include <stdlib.h>
// ...
// ...
int r = arc4random_uniform(74);

La arc4random page de man:

NAME
     arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <stdlib.h>

     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))
989
répondu lajos 2015-08-10 23:09:28

utilisez la fonction arc4random_uniform(upper_bound) pour générer un nombre aléatoire dans une plage. Ce qui suit générera un nombre compris entre 0 et 73 inclusivement.

arc4random_uniform(74)

arc4random_uniform(upper_bound) évite modulo biais comme décrit dans la page de man:

arc4random_uniform () retournera un nombre aléatoire uniformément distribué inférieur à upper_bound. arc4random_uniform() est recommandé sur les constructions comme `arc4random() % upper_bound" car il évite les " modulo biais " lorsque la limite supérieure n'est pas une puissance de deux.

414
répondu yood 2017-05-23 12:02:47

même que C, Vous feriez

#include <time.h>
#include <stdlib.h>
...
srand(time(NULL));
int r = rand() % 74;

(en supposant que vous vouliez dire inclure 0 mais en excluant 74, ce qui est ce que fait votre exemple Java)

Edit: libre à vous de remplacer random() ou arc4random() pour rand() (qui est, comme d'autres l'ont souligné, tout à fait sucky).

61
répondu James Ko 2016-02-06 18:32:09

j'ai pensé que je pourrais ajouter une méthode que j'utilise dans de nombreux projets.

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

si je finis par l'utiliser dans de nombreux fichiers je déclare habituellement une macro comme

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

E. G.

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

Note: uniquement pour ios 4.3/OS X v10.7 (Lion) et plus tard

43
répondu Groot 2015-10-26 16:59:50

cela vous donnera un floating point nombre entre 0 et 47

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

ou tout simplement

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

les limites inférieure et supérieure peuvent être négative ainsi. Le code d'exemple ci-dessous vous donne un nombre aléatoire entre -35.76 et + 12.09

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

Convertir résultat à un rond Integer valeur:

int intRndValue = (int)(rndValue + 0.5);
42
répondu Tibidabo 2012-02-20 00:55:52

D'après la page de manuel de rand(3), la famille de fonctions rand a été obsolète au hasard(3). Ceci est dû au fait que les 12 bits inférieurs de rand() passent par un pattern cyclique. Pour obtenir un nombre aléatoire, il suffit de lancer le générateur en appelant srandom() avec une graine non signée, puis d'appeler random(). Ainsi, l'équivalent du code ci-dessus serait

#import <stdlib.h>
#import <time.h>

srandom(time(NULL));
random() % 74;

vous n'aurez besoin d'appeler srandom() qu'une seule fois dans votre programme à moins que vous ne vouliez changer votre graine. Bien que vous ayez dit que vous ne vouliez pas une discussion sur les valeurs vraiment aléatoires, rand() est un très mauvais générateur de nombres aléatoires, et random() souffre toujours de biais modulo, car il générera un nombre entre 0 et RAND_MAX. Donc, par exemple si RAND_MAX est 3, et que vous voulez un nombre aléatoire entre 0 et 2, Vous êtes deux fois plus susceptible d'obtenir un 0 qu'un 1 ou un 2.

34
répondu Michael Buckley 2008-10-02 06:49:40

mieux utiliser arc4random_uniform . Cependant, ce n'est pas disponible en dessous de ios 4.3. Heureusement, iOS liera ce symbole à l'exécution, pas à la compilation (n'utilisez donc pas la directive #if preprocessor pour vérifier si elle est disponible).

la meilleure façon de déterminer si arc4random_uniform est disponible est de faire quelque chose comme ceci:

#include <stdlib.h>

int r = 0;
if (arc4random_uniform != NULL)
    r = arc4random_uniform (74);
else
    r = (arc4random() % 74);
30
répondu AW101 2014-02-18 20:55:27

j'ai écrit ma propre classe d'utilité de nombres aléatoires juste pour avoir quelque chose qui fonctionnait un peu plus comme les mathématiques.random () en Java. Il n'a que deux fonctions, et tout est fait en C.

fichier d'en-Tête:

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

la mise en Œuvre de fichier:

//Random.m
static unsigned long seed;

void initRandomSeed(long firstSeed)
{ 
    seed = firstSeed;
}

float nextRandomFloat()
{
    return (((seed= 1664525*seed + 1013904223)>>16) / (float)0x10000);
}

c'est une façon assez classique de générer des pseudo-randoms. Dans mon délégué app j'appelle:

#import "Random.h"

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

plus tard je dis juste:

float myRandomNumber = nextRandomFloat() * 74;

cette méthode renvoie un nombre aléatoire compris entre 0,0 f (inclusivement) et 1,0 f (exclusif).

12
répondu Eli 2010-01-28 00:02:39

il y a déjà de grandes réponses articulées, mais la question demande un nombre aléatoire entre 0 et 74. Use:

arc4random_uniform(75)

6
répondu Tom Howard 2015-05-11 15:20:01

depuis iOS 9 et OS X 10.11, vous pouvez utiliser les nouvelles classes GameplayKit pour générer des nombres aléatoires de différentes façons.

vous avez quatre types de sources à choisir: une source aléatoire générale (unnamed, down to the system to choose what it does), linéaire congruential, ARC4 et Mersenne Twister. Ceux-ci peuvent générer des entiers, des flotteurs et des booléens.

au niveau le plus simple, vous pouvez générer un nombre aléatoire à partir du système intégré random source:

NSInteger rand = [[GKRandomSource sharedRandom] nextInt];

qui génère un nombre entre -2.147.483.648 et 2.147.483.647. Si vous voulez un nombre entre 0 et une limite supérieure (exclusive) vous utiliserez ceci:

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

GameplayKit a quelques constructeurs de commodité intégrés pour travailler avec des dés. Par exemple, vous pouvez rouler un dé à six faces comme ceci:

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

Plus vous pouvez façonner la distribution aléatoire en utilisant des choses comme GKShuffledDistribution .

3
répondu TwoStraws 2015-12-19 13:23:48

génère un nombre aléatoire entre 0 et 99:

int x = arc4random()%100;

génère un nombre aléatoire entre 500 et 1000:

int x = (arc4random()%501) + 500;
2
répondu adijazz91 2015-05-21 11:56:54

//L'exemple suivant va générer un nombre entre 0 et 73.

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);

sortie:

  • nombre aléatoire: 72

  • nombre aléatoire étape 2: 52

2
répondu Sujania 2015-09-29 09:51:44

Pour game dev utiliser random() pour générer des randoms. Probablement au moins 5 fois plus rapide que l'utilisation d'arc4random(). Le biais Modulo n'est pas un problème, surtout pour les jeux, quand on génère des random en utilisant toute la gamme de random(). Assurez-vous de graine en premier. Appel srandomdev() dans AppDelegate. Voici quelques fonctions d'aide:

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;}
0
répondu Robert Wasmann 2016-07-15 04:55:28