Domanda

Sono principalmente un capo Java e voglio un modo per generare un numero pseudo-casuale tra 0 e 74. In Java userei il metodo:

Random.nextInt(74)

Non sono interessato a una discussione sui semi o sulla vera casualità, proprio come si compie lo stesso compito in Objective-C. Ho cercato Google e sembra che ci siano molte informazioni diverse e contrastanti.

È stato utile?

Soluzione

Dovresti usare la funzione arc4random_uniform () . Utilizza un algoritmo superiore per rand . Non è nemmeno necessario impostare un seme.

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

La pagina man 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))

Altri suggerimenti

Utilizza la funzione arc4random_uniform (upper_bound) per generare un numero casuale all'interno di un intervallo. Di seguito verrà generato un numero compreso tra 0 e 73 inclusi.

arc4random_uniform(74)

arc4random_uniform (upper_bound) evita polarizzazione del modulo come descritto nella pagina man:

  

arc4random_uniform () restituirà un numero casuale uniformemente distribuito inferiore a upper_bound. arc4random_uniform () è consigliato su costruzioni come `` arc4random ()% upper_bound '' poiché evita " modulo bias " quando il limite superiore non è una potenza di due.

Come C, lo faresti

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

(supponendo che intendessi includere 0 ma escluso 74, che è ciò che fa il tuo esempio Java)

Modifica: sentiti libero di sostituire random () o arc4random () con rand () (che è, come altri hanno sottolineato, abbastanza schifoso).

Ho pensato di poter aggiungere un metodo che uso in molti progetti.

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

Se finisco per usarlo in molti file di solito dichiaro una macro come

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

per es.

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

Nota: solo per iOS 4.3 / OS & nbsp; X & nbsp; v10.7 (Lion) e versioni successive

Questo ti darà un virgola mobile un numero compreso tra 0 e 47

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

O semplicemente

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

Anche il limite inferiore e superiore possono essere negativi . Il seguente codice di esempio fornisce un numero casuale compreso tra -35,76 e +12,09

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

Converti il ??risultato in un valore intero più arrotondato:

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

Secondo la pagina di manuale di rand (3), la famiglia di funzioni rand è stata superata da random (3). Ciò è dovuto al fatto che i 12 bit inferiori di rand () passano attraverso un modello ciclico. Per ottenere un numero casuale, esegui il seeding del generatore chiamando srandom () con un seed non firmato, quindi chiama random (). Quindi, l'equivalente del codice sopra sarebbe

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

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

Devi solo chiamare srandom () una volta nel tuo programma a meno che tu non voglia cambiare il tuo seed. Sebbene tu abbia detto che non volevi una discussione su valori veramente casuali, rand () è un generatore di numeri casuali piuttosto male, e random () soffre ancora di bias del modulo, in quanto genererà un numero compreso tra 0 e RAND_MAX. Quindi, ad es. se RAND_MAX è 3 e desideri un numero casuale compreso tra 0 e 2, hai il doppio delle probabilità di ottenere uno 0 rispetto a 1 o 2.

Meglio usare arc4random_uniform . Tuttavia, questo non è disponibile sotto iOS 4.3. Fortunatamente iOS vincolerà questo simbolo in fase di esecuzione, non in fase di compilazione (quindi non utilizzare la direttiva preprocessore #if per verificare se è disponibile).

Il modo migliore per determinare se arc4random_uniform è disponibile è fare qualcosa del genere:

#include <stdlib.h>

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

Ho scritto la mia classe di utilità per i numeri casuali solo per avere qualcosa che funzionasse un po 'più come Math.random () in Java. Ha solo due funzioni ed è tutto realizzato in C.

File di intestazione:

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

File di implementazione:

//Random.m
static unsigned long seed;

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

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

È un modo abbastanza classico di generare pseudo-random. Nel delegato della mia app chiamo:

#import "Random.h"

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

Poi dopo dico solo:

float myRandomNumber = nextRandomFloat() * 74;

Nota che questo metodo restituisce un numero casuale compreso tra 0.0f (incluso) e 1.0f (esclusivo).

Ci sono già alcune risposte grandi e articolate, ma la domanda richiede un numero casuale compreso tra 0 e 74. Usa:

arc4random_uniform (75)

A partire da iOS 9 e OS X 10.11, puoi utilizzare le nuove classi GameplayKit per generare numeri casuali in vari modi.

Puoi scegliere tra quattro tipi di sorgente: una fonte casuale generale (senza nome, fino al sistema per scegliere cosa fare), lineare congruenziale, ARC4 e Mersenne Twister. Questi possono generare ints, float e bool casuali.

Al livello più semplice, puoi generare un numero casuale dalla fonte casuale incorporata del sistema in questo modo:

NSInteger rand = [[GKRandomSource sharedRandom] nextInt];

Ciò genera un numero compreso tra -2.147.483.648 e 2.147.483.647. Se si desidera un numero compreso tra 0 e un limite superiore (esclusivo), si utilizzerà questo:

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

GameplayKit ha alcuni costruttori di convenienza integrati per lavorare con i dadi. Ad esempio, puoi tirare un dado a sei facce in questo modo:

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

Inoltre puoi modellare la distribuzione casuale usando cose come GKShuffledDistribution .

Genera un numero casuale compreso tra 0 e 99:

int x = arc4random()%100;

Genera un numero casuale compreso tra 500 e 1000:

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

// Il seguente esempio genererà un numero compreso tra 0 e 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);

Output:

  • numero casuale: 72

  • passaggio numero casuale 2: 52

Per gli sviluppatori di giochi usa random () per generare randoms. Probabilmente almeno 5 volte più veloce rispetto all'uso di arc4random (). La distorsione da modulo non è un problema, specialmente per i giochi, quando si generano random usando l'intera gamma di random (). Assicurati di seminare prima. Chiama srandomdev () in AppDelegate. Ecco alcune funzioni di supporto:

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;}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top