1
votes

I'm hoping to find a way to fill an array with random floating point numbers. My array is size 50 and I'm hoping to fill this array with random float numbers from range 1-25. Here is what I have so far. I greatly appreciate any tips or answers anyone can offer. Thank you.

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;


int main()

{

float myArray[50];


for(int i = 1; i <= 25; i++)

{

srand(time(0));


myArray[i] = (rand()% 50 + 1);

cout << myArray[i] << endl;



system("Pause");

return 0;

} 

}
5
Use classes from <random>. - Siyuan Ren
Do not do srand in the loop, the time will be the same at least between some of the calls. - Sergey Kalinichenko
You're currently only half-filling your array - i needs to go up to 50 and your modulus needs to be 25. - Andy Royal

5 Answers

10
votes

If C++11 is an option I would use the random header and uniform_real_distribution:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());
    std::uniform_real_distribution<> dist(0, 25);

    for (int n = 0; n < 50; ++n) {
        std::cout << dist(e2) << ",";
    }
    std::cout << std::endl ;
}

Why do people say there is modulo bias when using a random number generator? explains why the naive use of modulus with rand() causes bias in the distribution and how to avoid it.

5
votes

If C++11 is not an option, you can just use rand, dividing its result by the RAND_MAX constant casted to float to obtain a uniform distribution of floats in the range [0, 1]; then you can multiply it by 24 and add 1 to get your desired range:

myArray[i] = rand()/float(RAND_MAX)*24.f+1.f;

By the way, as other observed, move srand out of your loop - the RNG seed (normally) must be initialized only once.

(notice that dividing by RAND_MAX will give a distribution that includes the right extreme of your interval; if you want to exclude it, you should divide by e.g. RAND_MAX+1)


Of course, the resulting distribution is only as good as the original rand() distribution (both in randomness and in granularity); you will typically get a LCG and granularity of at least ~0.0007 (guaranteed by the standard, and what VC++ and other compilers actually provide). If you need better random numbers, you should follow the advices posted in the other answers (the default Mersenne twister generator in C++11 provides better randomness and a way bigger guaranteed range).

1
votes
#include <random>
...
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> dist(1.0f, 25.0f);

std::cout << dist(gen);
1
votes

Each time the for loop iterates, it assigns one value in the array a random number. Since your array is of size 50, you want to iterate 50 times instead of 25 like you do now.

for(int i = 0; i < 50; i++)

Array bounds start at 0, so you can only access from array[0] to array[49].

To get a random number from 1-25, you want

myArray[i] = rand() % 25 + 1;

Also, do you want integers or floating point random numbers? Right now you are just getting integers, meaing 1, 2, 3, ... 25. If you want something like 2.45, 6.883, 23.999, etc. you need to do something different. See C++ random float number generation for the answer.

You probably don't want to pause every time you insert a number into the array. Move this after the for loop.

system("pause");

Also, if you return 0 inside the for loop, you will only assign one number before your program will exit. Move that to after the loop as well.

0
votes

Use uniform_real. In the following program random float numbers between 1.0 and 2.0 are generated:

#include <random> 
#include <iostream> 

typedef std::ranlux64_base_01 Myeng; 
typedef std::uniform_real<float> Myceng; 
int main() 
{ 
    Myeng eng; 
    Myceng ceng(1.0, 2.0); 
    Myceng::input_type engval = eng(); 

    std::cout << "a random value == " << ceng(eng) << std::endl; 
    std::cout << "a random value == " << ceng(eng) << std::endl; 
    std::cout << "a random value == " << ceng(eng) << std::endl; 

    return (0); 
}