2015-10-10 15 views
5

Pracuję nad tym od jakiegoś czasu i mam wiele problemów. Chcę wygenerować losową wartość z -1 na 1 dla obliczeń. Nie mogę użyć operatora%, ponieważ jest on przeznaczony tylko dla liczb całkowitych. Próbowałem również używać fmod(), ale mam tu również trudności.Generuj losowe podwójne od -1 do 1

Co starałem się stosowania był ...

double random_value; 
random_value = fmod((double) rand(),2) + (-1); 

wydaje się, że to nie jest poprawne, choć. Próbowałem też do materiału siewnego srand z czasem, ale myślę, że robię coś źle tam, bo ciągle rzuca ten błąd:

"error: expected declaration specifiers or '...' before time" 

Kod:

srand((unsigned) time(&t)); 

jakiejkolwiek pomocy z tych problemów byłoby docenić.

+0

rand() nadal zwraca liczbę całkowitą, a potem rzucają go podwoić. Oznacza to, że możliwe rozwiązania to -1,0 i 1, żadne inne podwójne nie są możliwe. Spójrz na [c-random-float-number-generation] (http://stackoverflow.com/questions/686353/c-random-float-number-generation) –

+0

Odpowiedzi dostarczone do tej pory (w tym moje) nie obejmą pełny zakres precyzji dostępny w "podwójnym". Jaką precyzję potrzebujesz? –

+0

Edytowałem swoją odpowiedź, aby odzwierciedlić ograniczenia precyzji. Podaj więcej informacji o swoich wymaganiach, jeśli chcesz czegoś "lepszego". –

Odpowiedz

4

będzie to ziarno generatora liczb losowych i dać podwójny w zakresie od -1.0 do 1.0

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

int main() 
{ 
    double random_value; 

    srand (time (NULL)); 

    random_value = (double)rand()/RAND_MAX*2.0-1.0;//float in range -1 to 1 

    printf ("%f\n", random_value); 

    return 0; 
} 
+2

Uwaga: To spowoduje co najwyżej "RAND_MAX + 1" różne wartości, nawet jeśli w zakresie -1 do 1 może być wiele innych wartości "double". – chux

3

Można materiału siewnego czasu (raz przed wszystkich wywołań rand) jak poniżej:

#include <time.h> 

// ... 
srand (time (NULL)); 

Za pomocą tej funkcji można w razie potrzeby ustawić min/maks.

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

/* generate a random floating point number from min to max */ 
double randfrom(double min, double max) 
{ 
    double range = (max - min); 
    double div = RAND_MAX/range; 
    return min + (rand()/div); 
} 

Źródło: [SOLVED] Random double generator problem (C Programming) na Ubuntu Forums

Wtedy to nazwać tak:

double myRand = randfrom(-1.0, 1.0); 

jednak pamiętać, że to najprawdopodobniej nie obejmie pełny zakres dostępnej z precyzją a double. Bez uwzględnienia wykładnika, IEEE-754 double zawiera 52 bity znaczące (to jest część nie-wykładnikową). Od rand zwraca int między 0 i RAND_MAX, maksymalna możliwa wartość RAND_MAX jest INT_MAX. Na wielu (najbardziej?) Platformach, int jest 32-bitowe, więc INT_MAX jest 0x7fffffff, obejmując 31 bitów zakresu.

+1

Musisz '#include ' użyć 'time (NULL)'. – harre

+0

@ Pożegnanie, dzięki - dodane. :) –

0
nie

chyba dobry pomysł, aby to zrobić, ale tylko dlatego, że to działa, oto sposobem generowania losowych podwoić między -1 a 1 obejmowały wykorzystanie /dev/urandom i cos():

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <math.h> 

int main() 
{ 
    int fd; 
    double x; 

    fd = open("/dev/urandom", O_RDONLY); 
    if (fd == -1) 
    return (1); 
    read(fd, &x, sizeof(x)); 
    close(fd); 
    x = cos(x); 
    printf("%f\n", x); 
    return (0); 
} 
+0

Lol przy twórczym wykorzystaniu cosinusów. –

+1

Każdego tysiąca rozmów lub mniej, otrzymasz NaN. (Nie ze względu na cos, chociaż uważam, że cos (nieskończoność) jest również NaN, ale bardzo rzadko dostaniesz nieskończoność). To, co jest związane z cos, to to, że rng tutaj nie będzie równomiernie rozłożony. – rici

0

Myślę, że najlepszym sposobem aby stworzyć prawdziwe losowe podwójne, należy użyć jego struktury. Here - artykuł o tym, jak przechowywane są liczby zmiennoprzecinkowe. Jak widzisz, jedynym ograniczającym warunkiem dla wartości zmiennoprzecinkowej w zakresie od 1 do -1 jest to, że wartość wykładnika nie przekracza 128.

Ieee754SingleDigits2Double konwertuje ciąg od 0s i 1s do zmiennej zmiennoprzecinkowej i zwraca ją. Mam to z odpowiedzi na pytanie this.

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

double Ieee754SingleDigits2Double(const char s[32]) 
{ 
    double f; 
    int sign, exp; 
    unsigned int mant; 
    int i; 

    sign = s[0] - '0'; 

    exp = 0; 
    for (i = 1; i <= 8; i++) 
     exp = exp * 2 + (s[i] - '0'); 

    exp -= 127; 


    if (exp > -127) 
    { 

     mant = 1; // The implicit "1." 
     exp -= 23; 
    } 
    else 
    { 
     mant = 0; 
     exp = -126; 
     exp -= 23; 
    } 

    for (i = 9; i <= 31; i++) 
     mant = mant * 2 + (s[i] - '0'); 

    f = mant; 

    while (exp > 0) 
     f *= 2, exp--; 

    while (exp < 0) 
     f /= 2, exp++; 

    if (sign) 
     f = -f; 

    return f; 
} 

Oto główną funkcją:

int main(void) 
{ 
    srand (time (NULL)); 
    int i; 
    char s[33]; 
    for(i = 0; i < 32; i++) 
    { 
     if(i == 1) 
      continue; 
     s[i] = rand() % 2 + '0'; 
    } 
    s[1] = '0'; 
    s[32] = 0; 
    printf("%s\n", s); 
    printf("%+g\n", Ieee754SingleDigits2Double(s)); 

    return 0; 
} 
Powiązane problemy