Generating a random double between a range of values

后端 未结 5 1320
天涯浪人
天涯浪人 2021-01-13 18:33

Im currently having trouble generating random numbers between -32.768 and 32.768. It keeps giving me the same values but with a small change in the decimal field. ex : 27.xx

相关标签:
5条回答
  • 2021-01-13 18:40

    I've added a for loop to your program:

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

    Example output:

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

    It seems Okay to me. I've added the code on Ideone for you.

    Here are four runs:

     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
    

    Perhaps you're not waiting at least a second between runs?

    0 讨论(0)
  • 2021-01-13 18:43

    It seams to be plainly obvious but some of the examples say otherwise... but i thought when you divide 1 int with another you always get an int? and you need to type cast each int to double/float before you divide them.

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

    also if you call srand() every time you call rand() you reset the seed which results in similar values returned every time instead of ''random'' ones.

    0 讨论(0)
  • 2021-01-13 18:50

    I should mention if you're using a C++11 compiler, you can use something like this, which is actually easier to read and harder to mess up:

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

    As bames53 pointed out, the above code can be made even shorter if you make full use of 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 讨论(0)
  • 2021-01-13 18:56

    So, I think this is a typical case of "using time(NULL) isn't a great way of seeding random numbers for runs that start close together". There isn't that many bits that change in time(NULL) from one call to the next, so random numbers are fairly similar. This is not a new phenomena - if you google "my random numbers aren't very random", you'll find LOTS of this.

    There are a few different solutions - getting a microsecond or nanosecond time would be the simplest choice - in Linux gettimeofday will give you a microsecond time as part of the struct.

    0 讨论(0)
  • 2021-01-13 19:02

    Also, If you are not using c++ 11 you can use the following function instead:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题