objective c - oxidasa - Generando números aleatorios en Objective-C




citocromo oxidasa (9)

// El siguiente ejemplo va a generar un número entre 0 y 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);

Salida:

  • número aleatorio: 72

  • número al azar paso 2: 52

Soy un jefe de Java principalmente, y quiero una forma de generar un número pseudoaleatorio entre 0 y 74. En Java usaría el método:

Random.nextInt(74)

No estoy interesado en una discusión sobre las semillas o la verdadera aleatoriedad, solo cómo lograr la misma tarea en Objective-C. He rastreado Google y parece que hay mucha información diferente y conflictiva.


A partir de iOS 9 y OS X 10.11, puede usar las nuevas clases GameplayKit para generar números aleatorios de varias maneras.

Tiene cuatro tipos de fuentes para elegir: una fuente aleatoria general (sin nombre, hasta el sistema para elegir lo que hace), congruente lineal, ARC4 y Mersenne Twister. Estos pueden generar entradas aleatorias, flotadores y bools.

En el nivel más simple, puede generar un número aleatorio a partir de la fuente aleatoria incorporada del sistema de esta manera:

NSInteger rand = [[GKRandomSource sharedRandom] nextInt];

Eso genera un número entre -2,147,483,648 y 2,147,483,647. Si desea un número entre 0 y un límite superior (exclusivo), use este:

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

GameplayKit tiene algunos constructores de conveniencia integrados para trabajar con dados. Por ejemplo, puedes tirar un dado de seis caras como este:

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

Además, puede configurar la distribución aleatoria utilizando elementos como GKShuffledDistribution .


Deberías usar la función arc4random_uniform (). Utiliza un algoritmo superior para rand. Ni siquiera necesitas poner una semilla.

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

La página del manual de arc4random:

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

Escribí mi propia clase de utilidad de números aleatorios para tener algo que funcionara un poco más como Math.random () en Java. Tiene solo dos funciones, y todo está hecho en C.

Archivo de cabecera:

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

Archivo de implementación:

//Random.m
static unsigned long seed;

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

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

Es una forma bastante clásica de generar pseudo-randoms. En mi aplicación delegado llamo:

#import "Random.h"

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

Luego más tarde solo digo:

float myRandomNumber = nextRandomFloat() * 74;

Tenga en cuenta que este método devuelve un número aleatorio entre 0.0f (incluido) y 1.0f (exclusivo).


Generar número aleatorio entre 0 a 99:

int x = arc4random()%100;

Generar número aleatorio entre 500 y 1000:

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

Igual que C, harías

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

(Suponiendo que te refieres a incluir 0 pero excluyendo 74, que es lo que hace tu ejemplo de Java)

Edición: siéntase libre de sustituir random() o arc4random() por rand() (que es, como otros han señalado, bastante sucky).


Para el juego dev use random () para generar randoms. Probablemente al menos 5 veces más rápido que usar arc4random (). El sesgo de módulo no es un problema, especialmente para los juegos, al generar randoms utilizando toda la gama de random (). Asegúrate de sembrar primero. Llame a srandomdev () en AppDelegate. Aquí hay algunas funciones de ayuda:

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

Pensé que podría agregar un método que uso en muchos proyectos.

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

Si termino usándolo en muchos archivos normalmente declaro una macro como

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

P.ej

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

Nota: solo para iOS 4.3 / OS X v10.7 (Lion) y versiones posteriores


Ya hay algunas respuestas excelentes y articuladas, pero la pregunta pide un número aleatorio entre 0 y 74. Use:

arc4random_uniform(75)







random