Rand() giving very similar output each iteration

I'm trying to use rand() to create pseudo-random numbers between 0 and 1 inclusively. I have the following code but each time I run it, I get a number very close to .13, like .13455 or .13110. I never get anything different.
I would prefer it to be as pseudo-random as possible because I will be using these random numbers to calculate the value of pie. Why isn't it working properly for me like it is for everyone else?

1
2
3
4
5
6
7
8
9
10
11
#include "pch.h"
#include <iostream>
#include <ctime>
#include <cstdlib>

int main()
{
	srand(static_cast <unsigned> (time(0)));
	float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
	std::cout << r << std::endl;
}
Last edited on
There's no reason that it should be doing that. It certainly doesn't do that for me.

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
    std::srand(std::time(nullptr));
    auto r = double(std::rand()) / RAND_MAX;
    std::cout << r << '\n';
}

Last edited on
It is because you are using static_cast to tell the compiler that the int is really a float. Don’t tell the compiler to ignore the type of things. dutch’s code works because it is doing a proper type conversion from int to double (or float, if you desire).
C++11 has excellent tools to create floating point random numbers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <chrono>   // for std::chrono::system_clock
#include <random>   // for std::default_random_engine & std::uniform_real_distribution

int main()
{
  // construct a trivial random generator engine from a time-based seed:
   unsigned seed = static_cast<unsigned> (std::chrono::system_clock::now().time_since_epoch().count());
   std::default_random_engine generator(seed);

   // create a distribution that generates random numbers between 0.0 and 1.0 inclusive
   std::uniform_real_distribution<double> distribution(0.0, 1.0);

   std::cout << "some random numbers between 0.0 and 1.0:\n\n";

   for (size_t i = 0; i < 25; ++i)
   {
      std::cout << distribution(generator) << "   ";

      if (((i + 1) % 5) == 0) { std::cout << '\n'; }
   }
}
some random numbers between 0.0 and 1.0:

0.56886   0.901473   0.733938   0.573479   0.305482
0.793049   0.290057   0.575344   0.815751   0.995736
0.167663   0.224303   0.203236   0.680722   0.530791
0.736965   0.946262   0.500914   0.136686   0.468936
0.274314   0.783668   0.0474963   0.104416   0.115558
@Duthomhas, Are you thinking of reinterpret_cast? The static_cast works. If you click the little gear to run it in C++Shell (and comment out the #include "pch") it works, giving different results each run.

But it seems to be a MSVC compiler issue. If you run it here:
https://rextester.com/l/cpp_online_compiler_visual
then it gives bad results. rand() returns values very close to the last value if only a few seconds have passed. (And RAND_MAX is still only 32767 for that compiler.) Here's some results showing time(0), rand() and double(rand)/RAND_MAX:
time(0)      rand()   /RAND_MAX
1553918351   23808    0.726585
1553918361   23841    0.727592
1553918378   23897    0.729301


So Furry Guy has the right advice, I think. Use the new random features, which we should always be using anyway.
Last edited on
@dutch I don't understand, even when I use your code from your first post, my results look like this.
First run: 0.415967
Second run: 0.417676
Third run: 0.419172
After waiting a minute, the result is now 0.422864
It seems to go up as the time increases.
@Furry Guy So I realize that my compiler is too old to use this new technique. Should I update MSVC or go with a different compiler? And if so, which?
You are using Visual Studio, right? The #include "pch.h" is a dead give-away.

If you want to use srand()/rand() in C++ code, and that is not recommended, you need to discard at least the first number you get from rand().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <ctime>
#include <cstdlib>

int main()
{
	srand(static_cast <unsigned> (time(0)));

        // discard the first random number generated to get around the known VS "bug"
        std::rand();

        // now you will get a more randomized distribution
        auto r = double(std::rand()) / RAND_MAX;
	std::cout << r << std::endl;
}

The VS "bug" is another reason why I don't use the C library random functions in C++ code without very good reasons otherwise.

There are other reasons for not using them as well.
Last edited on
Ideally, update the compiler: https://visualstudio.microsoft.com/vs/community/
(In the installer, choose Desktop Development with C++)

With the old compiler, try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <ctime>
#include <cstdlib>

int main()
{
    std::srand( static_cast <unsigned> (time(0) ) ) ;
    
    // added
    const int N = std::rand() % 1000 + 100;
    for( int i = 0 ; i < N ; ++i ) std::rand() ;

    const float r = static_cast <float> ( std::rand() ) / RAND_MAX ;
    std::cout << r << std::endl;
}

Last edited on
@Crusher21, what is your VS version?

Anything less than VS 2015 is a waste of time and effort. You need ANY compiler/IDE that supports C++11, and hopefully C++17 and later. It doesn't have to be VS.

IMO even VS2015 is outdated. VS2017 is the current version available, with VS2019 about to be released early in April.

You already use VS, so getting a newer version will be less of a problem learning how to use it vs. getting an entirely different compiler/IDE like Code::Blocks.


@Furry Guy I prefer to use the new method that you proposed.
I'm using Visual Studio 2017 Community version, I installed it last night when I realized I didn't have Visual Studio installed. I'm very surprised that it didn't come with an up to date compiler. Checking for updates revealed that I was up to date, using version 15.9.10.

I don't have experience with using different compilers or even installing them to be able to use them. I always just use whatever Visual Studio comes with.

@JLBorges I already have the latest version of the 2017 Community edition. How can I update the compiler that comes with it? I tried downloading Microsoft Visual C++ 2017 Redistributable 14.16.27027 but the setup always fails saying there is another version already installed.
VS2017 DOES have an up-to-date C++17/C++latest compiler. It defaults to C++14, you can change your project's language settings to use a more recent language standard. If you want.

Since the <chrono> and <random> libraries need C++11 OR LATER, you shouldn't need to worry what language standard you set for the code sample I posted.

Create an empty console project, add an empty C++ source file, copy 'n' paste the code I posted and VS2107 (my IDE/compiler) will happily digest the code I wrote and spit out an executable.

If it doesn't then there is likely to be problems with your installation.

Depending on if you compiled in debug or release mode you can start the app with either F5 or CTRL+F5.

I use the Windows Desktop Wizard for all my new projects. It lets me deselect using precompiled headers (only useful IMO when compiling LARGE projects/solutions), select an empty project and what type of project it is. Console, Windows, DLL, etc.
Topic archived. No new replies allowed.