2010-08-04 13 views
32

Sto provando a creare un float casuale tra 0.15 e 0.3 in Objective-C. Il codice seguente restituisce sempre 1:Come creare un float casuale in Objective-C?

int randn = (random() % 15)+15; 
float pscale = (float)randn/100; 

Che cosa sto facendo di sbagliato?

+0

questo codice sembra funzionare, utilizzare ancora 100.0f è migliore. Solo il caso che posso indovinare è che stai mettendo questo codice in una funzione e non dichiarandolo in .h, quindi il compilatore potrebbe aggiornarlo per raddoppiare. – chunkyguy

risposta

17

Prova questo:

(float)rand()/RAND_MAX 

O per ottenere uno tra 0 e 5:

float randomNum = ((float)rand()/RAND_MAX) * 5; 

Diversi modi per fare la stessa cosa.

+19

Questo è sbagliato. 'random()/RAND_MAX' non ti darà un valore a virgola mobile dato che nessuno dei due valori è a virgola mobile. Inoltre, il dominio di 'random()' non è 0 a RAND_MAX. Il dominio di 'rand()' e 'rand_r()' è. Quindi dovresti usare: '(float) rand()/RAND_MAX' per ottenere il risultato atteso. –

+1

Questo è sbagliato (rand()/RAND_MAX) ti darà zero. Il commento di Jonathan è vero. – Gorky

+18

Ragazzi, sapete che potete modificare le risposte, giusto? – hasen

4
  1. uso arc4random() o di semi i valori casuali
  2. provare

    float pscale = ((float)randn)/100.0f; 
    
3

Il codice funziona per me, produce un numero casuale compreso tra 0,15 e 0,3 (fornito I SEMI CON srandom()). Hai chiamato srandom() prima della prima chiamata a random()? Dovrai fornire srandom() con un valore entropico (molte persone usano solo srandom(time(NULL))).

Per la generazione di numeri casuali più gravi, dare un'occhiata a arc4random, che viene utilizzato per scopi crittografici. Questa funzione di numero casuale restituisce anche un tipo intero, quindi sarà comunque necessario eseguire il cast del risultato in un tipo a virgola mobile.

63

Ecco una funzione

- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber { 
float diff = bigNumber - smallNumber; 
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1))/RAND_MAX) * diff) + smallNumber; 
} 
+13

#define boris_random (smallNumber, bigNumber) ((((float) (arc4random()% ((unsigned) RAND_MAX + 1))/RAND_MAX) * (bigNumber - smallNumber)) + smallNumber) – chunkyguy

+0

@chunkyguy, Potresti riscrivere per favore questa risposta usando 'arc4random_uniform'? –

0

Utilizzando srandom() e rand() è a rischio quando si ha bisogno di randomizzazione vero con un po 'di sale galleggiante.

Su MAC_10_7, IPHONE_4_3 e versioni successive è possibile utilizzare arc4random_uniform (upper_bound) *. Permette di generare un vero intero casuale da zero a * upper_bound *.

Così si può provare il seguente

u_int32_t upper_bound = <some big enough integer>; 

float r = 0.3 * (0.5 + arc4random_uniform(upper_bound)*1.0/upper_bound/2); 
-5

ho finito per generare a interi uno per il numero intero reale e quindi un numero intero per il decimale. Poi mi unisco in una stringa poi analizzarlo a un floatvalue con la funzione "floatValue" ... non riuscivo a trovare un modo migliore e questo funziona per le mie intenzioni, spero che aiuta :)

int integervalue = arc4random() % 2; 
int decimalvalue = arc4random() % 9; 
NSString *floatString = [NSString stringWithFormat:@"%d.%d",integervalue,decimalvalue]; 
float randomFloat = [floatString floatValue]; 
+1

Questo è un modo incredibilmente complicato per fare una cosa semplice, e non è nemmeno corretto. (Ad esempio, non potrebbe mai generare '1.01'.) –

2

più facile.

+ (float)randomNumberBetween:(float)min maxNumber:(float)max 
{ 
    return min + arc4random_uniform(max - min + 1); 
} 
+1

' arc4random_uniform' genera un numero intero casuale. – Andy

0

Per aggiungere a @ risposta di Caladain, se si desidera che la soluzione per essere facile da usare come rand(), è possibile definire questi:

#define randf() ((CGFloat)rand()/RAND_MAX) 
#define randf_scaled(scale) (((CGFloat)rand()/RAND_MAX) * scale) 

Sentitevi liberi di sostituire CGFloat con double se don avere accesso a CoreGraphics.

Problemi correlati