5

我目前无法在 -32.768 和 32.768 之间生成随机数。它一直给我相同的值,但小数字段的变化很小。例如:27.xxx。

这是我的代码,任何帮助将不胜感激。

#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;
}
4

5 回答 5

12

我应该提一下,如果你使用的是 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;
}
于 2013-02-01T02:38:30.520 回答
0

此外,如果您不使用 c++ 11,则可以使用以下函数:

double randDouble(double precision, double lowerBound, double upperBound) {
 double random;
 random = static_cast<double>(((rand()%(static_cast<int>(std::pow(10,precision)*(upperBound - lowerBound) + 1))) + lowerBound*std::pow(10,precision)))/std::pow(10,precision);
 return random;
}
于 2019-11-24T22:19:56.427 回答
-1

我在for您的程序中添加了一个循环:

#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上添加了代码。

这里有四次运行:

 Run 1:
    -29.0863
    -22.3973
     34.1034
    -1.41155
    -2.60232
    -30.5257
     31.9254
    -17.0673
     31.7522
     28.227

Run 2:
    -14.2872
    -0.185124
    -27.3674
     8.12921
     22.4611
    -0.414546
    -21.4944
    -11.0871
     4.87673
     5.4545

Run 3:
    -23.9083
    -6.04738
    -6.54314
     30.1767
    -16.2224
    -19.4619
     3.37444
     9.28014
     25.9318
    -22.8807

Run 4:
     25.1364
     16.3011
     0.596151
     5.3953
    -25.2851
     10.7301
     18.4541
    -18.8511
    -0.828694
     22.8335

也许您在两次运行之间至少没有等待一秒钟?

于 2013-02-01T02:26:34.657 回答
-1

因此,我认为这是“使用 time(NULL) 不是为开始靠近的运行播种随机数的好方法”的典型案例。从一个调用到下一个调用的变化并不多time(NULL),因此随机数非常相似。这不是一个新现象——如果你用谷歌搜索“我的随机数不是很随机”,你会发现很多。

有几种不同的解决方案 - 获得微秒或纳秒时间将是最简单的选择 - 在 Linuxgettimeofday中,作为结构的一部分,您将获得微秒时间。

于 2013-02-01T02:31:31.353 回答
-1

接缝似乎很明显,但有些例子另有说明......但我认为当你将 1 个 int 与另一个相除时,你总是得到一个 int?并且您需要在划分它们之前将每个 int 类型转换为 double/float。

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

此外,如果您每次调用 rand() 时都调用 srand(),则您会重置种子,这会导致每次返回的值相似,而不是“随机”值。

于 2013-02-01T03:28:01.510 回答