2009-08-31 21 views
6

Estoy intentando generar al azar un número positivo o negativo y en lugar de preocuparme por el rango mayor, espero generar aleatoriamente 1 o -1 para multiplicar por mi otro azar número.Objetivo C: los resultados aleatorios son 1 o -1

Sé que esto se puede hacer con una regla más larga de generar 0 o 1 y luego verificar return y usarlo para multiplicar por 1 o -1.

Esperando que alguien sepa de una forma más fácil de configurar aleatoriamente el signo en un número. Tratando de mantener mi código tan limpio como sea posible.

Respuesta

22

me gusta usar arc4random(), ya que no requiere que la semilla del generador de números aleatorios. También devuelve convenientemente uint_32_t, por lo que no tiene que preocuparse de que el resultado esté entre 0 y 1, etc. Simplemente le dará un entero aleatorio.

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

+1 por simple y directo. –

+0

Muy inteligente, gracias! – kubilay

10

Si entiendo bien la pregunta, que desea una secuencia pseudoaleatoria de 1 y -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 
} 

Actualización: Ok, algo que me ha estado molestando desde que escribí esto. Una de las debilidades frecuentes de los RNG comunes es que los bits de orden baja pueden pasar por ciclos cortos. Es probablemente el mejor para probar un poco de orden superior:     random() & 0x80000 ? 1 : -1

+5

Por qué no '(random() y 2) - 1'? –

+2

Solo un recordatorio para aquellos que no están familiarizados con los números aleatorios generados por un sistema determinista; no son realmente aleatorios. Probablemente quiera llamar a 'srandomdev();' en algún punto conveniente de "inicio de aplicación". Solo necesita llamarlo una vez. Esto siembra el generador de números aleatorios con una fuente de bits razonablemente aleatorios, por lo que los resultados de 'random()' son '' más aleatorios ''. De lo contrario, 'random()' comienza exactamente con la misma semilla cada vez. – johne

+0

Suponiendo que estamos hablando de 'Xcode.app'/su aplicación Cocoa estándar, el lugar más obvio para poner una llamada a' srandom() 'está en el archivo' main.m' proporcionado por 'Xcode.app', en la función 'main()', justo antes de la llamada a 'NSApplicationMain()'. – johne

0

Para generar 1 o -1 directamente, se podría hacer:

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

Pero por qué te preocupa la gama más amplia?

+0

rand() tiene algunos problemas. tal vez uno debería considerar usar otra cosa. http://ianbullard.squarespace.com/journal/2009/4/28/why-you-should-never-use-rand.html – neoneye

-1

Este paso adicional no le dará ninguna "aleatoriedad" adicional. Simplemente genere su número de inmediato en el rango que necesita (por ejemplo, -10..10). Estándar rand() devolverá un valor de este rango: 0..1 Puede multiplicarlo por una constante para aumentar el rango del rango o puede agregar una constante para empujarlo hacia la izquierda/derecha en el eje X. P. ej. para generar valores aleatorios a partir de (-5..10) Rango tendrá: rand() * 15-5

+0

@johne - Creo que Dmitry confunde Java con ObjectiveC ... –

+0

Disculpe por la Confusión. No me refiero específicamente a ningún idioma, sino a una función genérica que devuelve un valor aleatorio (flotante) del rango de 0..1. Mi objetivo principal fue explicar cómo transformarlo a cualquier otro rango (es decir, que no necesita que se genere -1 o 1 valor aleatorio) – DmitryK

-1

rand le dará un número de 0 a RAND_MAX que cubrirá todos los bits en un int a excepción de la señal. Al desplazar el resultado que dejó 1 bit, se convierte el MSB firmado en el signo, pero se ha reducido a cero el 0 th bit, que puede volver a llenar con un bit aleatorio de otra llamada al rand. El código será algo como:

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

-1 para complicar demasiado un problema simple de Objective-C con C++ innecesariamente complejo. Por lo general, no me importaría lo suficiente sobre estos temas para rechazar votos, pero la biblioteca estándar C tiene funciones de números aleatorios perfectamente buenas que no requieren tirar en C++, lo que puede tener algunos efectos secundarios desagradables y complicar la compilación, el tiempo de ejecución, etc. –

+0

Saqué el espacio de nombres std ::, por lo que ahora es válido C. 'std :: rand' es el mismo' rand' que C utiliza, solo está protegido detrás del espacio de nombres 'std' para evitar colisiones. – fbrereto

0
return (((arc4random() & 2) * 2) - 1); 
Cuestiones relacionadas