2013-02-01 2 views
2

В настоящее время у меня возникают проблемы с генерацией случайных чисел от -32.768 до 32.768. Он продолжает давать мне те же значения, но с небольшим изменением в десятичном поле. ex: 27.xxx.Создание случайного двойника между диапазоном значений

Heres мой код, любая помощь будет оценена.

#include <iostream> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 

int main() 
{ 
    srand(time(NULL)); 
    double r = (68.556*rand()/RAND_MAX - 32.768); 
    cout << r << endl; 
    return 0; 
} 
+0

Вы пробовали использовать петлю. Поскольку время (NULL) не меняется с одной секунды до следующей, есть вероятность, что вы получаете одинаковый номер каждый раз. Микросекунда gettimeofday() также может работать лучше. –

ответ

6

Я должен упомянуть, если вы используете C++ 11 компилятора, вы можете использовать что-то вроде этого, что на самом деле легче читать и труднее напутает:

#include <random> 
#include <iostream> 
#include <ctime> 


int main() 
{ 
    //Type of random number distribution 
    std::uniform_real_distribution<double> dist(-32.768, 32.768); //(min, max) 

    //Mersenne Twister: Good quality random number generator 
    std::mt19937 rng; 
    //Initialize with non-deterministic seeds 
    rng.seed(std::random_device{}()); 

    // generate 10 random numbers. 
    for (int i=0; i<10; i++) 
    { 
     std::cout << dist(rng) << std::endl; 
    } 
    return 0; 
} 

Как bames53 отметил, приведенный выше код может быть даже меньше, если вы в полной мере использовать C++ 11:

#include <random> 
#include <iostream> 
#include <ctime> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    std::mt19937 rng; 
    std::uniform_real_distribution<double> dist(-32.768, 32.768); //(min, max) 
    rng.seed(std::random_device{}()); //non-deterministic seed 
    std::generate_n( 
     std::ostream_iterator<double>(std::cout, "\n"), 
     10, 
     [&]{ return dist(rng);}); 
    return 0; 
} 
+0

Мне нужен диапазон, указанный мной. Я бы использовал (int), если бы захотел этот диапазон – Olivier

+0

Ответ обновлен. – Carl

+0

Согласовано. Спасибо за указатели. Ответ обновлен :) – Carl

0

Я добавил цикл в программе:

#include <iostream> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 

int main() 
{ 
    srand(time(NULL)); 
    for (int i = 0; i < 10; ++i) 
    { 
     double r = (68.556*rand()/RAND_MAX - 32.768); 
     cout << r << endl; 
    } 
    return 0; 
} 

Пример вывода:

31.6779 
-28.2096 
31.5672 
18.9916 
-1.57149 
-0.993889 
-32.4737 
24.6982 
25.936 
26.4152 

кажется, хорошо для меня. Я поставил код на ideone для вас.

Вот четыре трассы:

-29,0863 -22,3973 34,1034 -1,41155 -2,60232 -30,5257 31,9254 -17,0673 31,7522 28,227
-14,2872 -0,185124 -27,3674 8,12921 22,4611 -0,414546 -21,4944 -11,0871 4,87673 5,4545
- 23,9083 -6,04738 -6,54314 30,1767 -16,2224 -19,4619 3,37444 9,28014 25,9318 -22,8807
25,1364 16,3011 0,596151 5,3953 -25,2851 10,7301 18,4541 -18,8511 -0,828694 22,8335

Может быть, вы не ждете по крайней мере, второй между запусками?

+0

Я знаю, что это работает, но когда вы снова запускаете программу, она продолжает давать тот же точный цикл, но с небольшими изменениями в десятичных знаках.Он дает тот же самый точный цикл – Olivier

+0

Является ли мой пример выше, похожим на вывод на 'ideone'? Я снова запустил его и получил: «30.3961 -13.9189 14.837 25.0323 -7.88294 24.9879 3.77392 18.4251 -8.11763 35.4337« затем »25.0197 31.0387 -10.2659 -8.66796 -28.1792 -6.34876 7.51343 -32.6934 -23.4206 -16.8222«. Я не уверен, что вы делаете неправильно (если вы не ждали меньше секунды между прогонами), но проблема не в вашем коде. –

+0

Да, я скопировал ваш код от ideone. Единственная проблема, я имею в том, что первое значение в цикле всегда одно и то же (небольшое изменение в десятичной системе). Остальное случайное. – Olivier

0

Итак, я думаю, что это типичный случай «использования времени (NULL) - отличный способ посеять случайные числа для прогонов, которые начинаются близко друг к другу». Существует не так много бит, которые меняются в time(NULL) от одного вызова к другому, поэтому случайные числа довольно схожи. Это не новое явление - если вы google, мои случайные числа не очень случайны », вы найдете много.

Существует несколько различных решений - получение микросекундного или наносекундного времени будет самым простым выбором - в Linux gettimeofday вы получите микросекундное время как часть структуры.

0

швы быть совершенно очевидно, но некоторые из примеров сказать иначе ... но я думал, что, когда вы разделите 1 Int с другим вы всегда получаете int? и вам нужно набирать cast каждый int, чтобы удваивать/плавать, прежде чем вы разделите их.

ie: double r = (68.556 * (double) rand()/(double) RAND_MAX - 32.768);

также, если вы вызываете srand() при каждом вызове rand(), вы возвращаете семя, которое приводит к одинаковым значениям, возвращаемым каждый раз вместо «случайных».

+0

Код не выполняет целочисленное деление; '68.556 * rand()/RAND_MAX' выглядит так:' (68.556 * rand())/RAND_MAX', что означает, что числитель является 'double'. – bames53

+0

ах, слева направо, я вижу. Я бы все же поставил его там, чтобы избежать непредвиденных проблем, когда позже меняю код. –