2009-08-31 15 views
6

Sto cercando generare casualmente un numero positivo o negativo e piuttosto che preoccupa la gamma più grande spero di generare casualmente 1 o -1 a solo moltiplicare per la mia altra casuale numero.Objective C - risultati casuali è 1 o -1

So che questo può essere fatto con una regola più di generare 0 o 1 e poi controllando ritorno e utilizzando che a sia moltiplicare per 1 o -1.

Sperando che qualcuno sa di un modo più semplice per impostare solo casualmente il segno su un numero. Cercando di mantenere il mio codice il più pulito possibile.

risposta

22

Mi piace usare arc4random() perché non richiede di inizializzare il generatore di numeri casuali. Restituisce anche convenientemente un uint_32_t, quindi non devi preoccuparti che il risultato sia tra 0 e 1, ecc. Ti darà un numero intero casuale.

int myRandom() { 
    return (arc4random() % 2 ? 1 : -1); 
} 
+0

+1 per semplice e diretto. –

+0

Molto intelligente, grazie! – kubilay

10

Se ho capito bene la domanda, si desidera una sequenza pseudocasuale di 1 e -1:

int f(void) 
{ 
     return random() & 1 ? 1 : -1; 
    // or... 
    // return 2 * (random() & 1) - 1; 
    // or... 
    // return ((random() & 1) << 1) - 1; 
    // or... 
    // return (random() & 2) - 1; // This one from Chris Lutz 
} 

Aggiornamento: Ok, qualcosa è stato preoccuparsi di me da quando ho scritto questo. Uno dei frequenti punti deboli dei comuni RNG è che i bit di ordine basso possono passare attraverso cicli brevi. E 'probabilmente meglio per testare un po' di ordine superiore:     random() & 0x80000 ? 1 : -1

+5

Perché non '(random() e 2) - 1'? –

+2

Solo un promemoria per quelle persone che non hanno familiarità con numeri casuali generati da un sistema deterministico - non sono davvero casuali. Probabilmente vorrai chiamare 'srandomdev();' in qualche comodo punto di "avvio dell'app". Devi solo chiamarlo una volta. Questo semina il generatore di numeri casuali con una fonte di bit ragionevolmente casuali, quindi i risultati di 'random()' sono "più casuali". Altrimenti, 'random()' inizia con lo stesso seme ogni volta. – johne

+0

Supponendo che stiamo parlando di 'Xcode.app'/la tua applicazione Cocoa standard, il posto più ovvio per effettuare una chiamata a' srandom() 'è nel file' main.m' di 'Xcode.app', in la funzione 'main()', appena prima della chiamata a 'NSApplicationMain()'. – johne

0

Per generare 1 o -1 direttamente, si potrebbe fare:

int PlusOrMinusOne() { 
    return (rand() % 2) * 2 - 1 
} 

Ma perché sei preoccupato per la gamma più ampia?

+0

rand() ha alcuni problemi. forse si dovrebbe considerare l'utilizzo di qualcos'altro. http://ianbullard.squarespace.com/journal/2009/4/28/why-you-should-never-use-rand.html – neoneye

-1

Questo passo in più non vi darà alcuna "casualità" aggiuntivo. Basta generare il numero immediatamente nell'intervallo di cui hai bisogno (ad es. -10..10). rand standard() restituirà un valore da questo intervallo: 0..1 si può moltiplicare per una costante per aumentare la durata del campo o è possibile aggiungere una costante a spingerla a sinistra/destra sul X-asse. E.g. per generare valori casuali da da (-5..10) Campo si avrà: rand() * 15-5

+0

@johne - Penso che Dmitry stia confondendo Java con ObjectiveC ... –

+0

Scusate per il confusione. Non intendevo alcun linguaggio specifico, ma piuttosto una funzione generica che restituisce un valore casuale (float) compreso nell'intervallo 0..1. Il mio obiettivo principale era quello di spiegare come trasformarlo in qualsiasi altro intervallo (cioè che non è necessario che -1 o 1 valore casuale generato) – DmitryK

-1

rand vi darà un numero da 0 a RAND_MAX che coprirà ogni bit in un int eccezione il segno Spostando questo risultato sinistra 1 bit girare il MSB firmato nel segno, ma hanno azzerato-out la 0 ° po ', che si può ripopolare con un po' casuale da un'altra chiamata a rand. Il codice sarà simile:

int my_rand() 
{ 
    return (rand() << 1) + (rand() & 1); 
} 
+1

-1 per la complicazione eccessiva di un semplice problema Objective-C con C++ inutilmente complesso. Di solito non mi importa abbastanza di tali problemi a downvote, ma la libreria C standard ha funzioni di numeri casuali perfettamente buone che non richiedono l'estrazione di C++, che possono avere alcuni effetti collaterali piuttosto sgradevoli e complicare la compilazione, il runtime, ecc. –

+0

Ho estratto lo std :: namespace, quindi è ora valido C. 'std :: rand' è lo stesso' rand' C utilizza, appena protetto dietro lo spazio dei nomi 'std' per evitare collisioni. – fbrereto

0
return (((arc4random() & 2) * 2) - 1); 
Problemi correlati