2012-11-16 15 views
21

Eventuali duplicati:
C++ random float
How to generate a random number in C?Come generare il numero float casuale C

non riesco a trovare una soluzione per trovare il numero float casuale dalla [0,a], dove a è un float definito dall'utente.

Ho provato quanto segue, ma non sembra funzionare correttamente.

float x=(float)rand()/((float)RAND_MAX/a) 
+1

http: // c- faq.com/lib/randrange.html – Ouadie

+2

E, naturalmente, https://www.google.com/search?q=How+to+generate+random+float+number+in+C – rid

+0

Grazie. Dovrebbe essere: float x = (float) rand()/((float) RAND_MAX/a) o float x = (float) rand()/((float) RAND_MAX/a + 1)? – fragon

risposta

39

Prova:

float x = (float)rand()/(float)(RAND_MAX/a); 

Per capire come funziona questo considerare quanto segue.

N = a random value in [0..RAND_MAX] inclusively. 

L'equazione di cui sopra (rimuovendo i stampi per chiarezza) diventa:

N/(RAND_MAX/a) 

Ma divisione per una frazione equivale a moltiplicare per detto di frazione reciproco, quindi questo è equivalente a:

N * (a/RAND_MAX) 

che può essere riscritta come:

a * (N/RAND_MAX) 

Considerando N/RAND_MAX è sempre un valore in virgola mobile compreso tra 0.0 e 1.0, questo genererà un valore compreso tra 0.0 e a.

In alternativa, è possibile utilizzare quanto segue, che fa effettivamente la suddivisione che ho mostrato sopra. Io in realtà preferisco questo semplicemente perché è più chiaro ciò che sta realmente accadendo (per me, comunque):

float x = ((float)rand()/(float)(RAND_MAX)) * a; 

Nota: la rappresentazione in virgola mobile di a deve essere esatto o questo non potrà mai colpire il caso limite assoluto di a (si avvicinerà). Vedi this article per i dettagli grintosi sul perché.

Esempio

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(int argc, char *argv[]) 
{ 
    srand((unsigned int)time(NULL)); 

    float a = 5.0; 
    for (int i=0;i<20;i++) 
     printf("%f\n", ((float)rand()/(float)(RAND_MAX)) * a); 
    return 0; 
} 

uscita

1.625741 
3.832026 
4.853078 
0.687247 
0.568085 
2.810053 
3.561830 
3.674827 
2.814782 
3.047727 
3.154944 
0.141873 
4.464814 
0.124696 
0.766487 
2.349450 
2.201889 
2.148071 
2.624953 
2.578719 
+6

Questo potrebbe essere davvero pessimo proprietà arrotondanti. rand() restituisce un int a 32 bit, che stai trasmettendo a un float a 32 bit, che farà sì che i valori siano quantizzati. Ad esempio, è 64 volte più probabile che otterrai il valore 1000000192 rispetto al valore 1, da 1000000161 a 1000000223 a tutto tondo a 1000000192. Puoi evitarlo eseguendo il cast a un double invece, quindi eseguendo il down down su un float alla fine : float ((double) rand()/(double) (RAND_MAX/a)). –

-1

Se si desidera generare un galleggiante a caso in un intervallo, provare una soluzione successiva.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 


float 
random_float(const float min, const float max) 
{ 
    if (max == min) return min; 
    else if (min < max) return (max - min) * ((float)rand()/RAND_MAX) + min; 

    // return 0 if min > max 
    return 0; 
} 


int 
main (const int argc, const char *argv[]) 
{ 
    srand(time(NULL)); 

    char line[] = "-------------------------------------------"; 

    float data[10][2] = { 
     {-10, 10}, 
     {-5., 5}, 
     {-1, 1}, 
     {-0.25, -0.15}, 
     {1.5, 1.52}, 
     {-1700, 8000}, 
     {-0.1, 0.1}, 
     {-1, 0}, 
     {-1, -2}, 
     {1.2, 1.1} 
    }; 

    puts(line); 
    puts("  From | Result |  To"); 
    puts(line); 


    int i; 
    for (i = 0; i < 10; ++i) { 
     printf("%12f | %12f | %12f\n", data[i][0], random_float(data[i][0], data[i][1]), data[i][1]); 
    } 

    puts(line); 

    return 0; 
} 

Un risultato (valori è volubile)

------------------------------------------- 
    From | Result |  To 
------------------------------------------- 
    -10.000000 |  2.330828 | 10.000000 
    -5.000000 | -4.945523 |  5.000000 
    -1.000000 |  0.004242 |  1.000000 
    -0.250000 | -0.203197 | -0.150000 
    1.500000 |  1.513431 |  1.520000 
-1700.000000 | 3292.941895 | 8000.000000 
    -0.100000 | -0.021541 |  0.100000 
    -1.000000 | -0.148299 |  0.000000 
    -1.000000 |  0.000000 | -2.000000 
    1.200000 |  0.000000 |  1.100000 
------------------------------------------- 
3

Si può anche generare in un intervallo [min, max] con qualcosa come

float float_rand(float min, float max) 
{ 
    float scale = rand()/(float) RAND_MAX; /* [0, 1.0] */ 
    return min + scale * (max - min);  /* [min, max] */ 
} 
Problemi correlati