Creating random coordinates

Pages: 12
Jul 20, 2016 at 4:36pm
Hello everyone,

I am very new to c++. And, I need to create random cordinates. I need to have my coordinate must lie with in -1<x<1 and -1<y<1. Can anyone please help me in solving the issue? I am very beginner in c++. Help be greatly appreciated!

Many thanks,
Muon444
Jul 20, 2016 at 4:49pm
closed account (E0p9LyTq)
Look at the support C++ has in the C++ library <random>, a good start would be looking at the Mersenne Twister 19937 generator (class) and the Uniform real distribution (class template).
http://www.cplusplus.com/reference/random/mt19937/
http://www.cplusplus.com/reference/random/uniform_real_distribution/

There are examples at the links how to use.

There will be people who scream that using the C library rand() function is easier, but there are serious problems with using it. It is outdated, sloppy and inefficient.

Writing new C++ using rand() is like trying to create a mnemonic memory circuit using stone knives and bear skins.
http://cpp.indi.frih.net/blog/2014/12/the-bell-has-tolled-for-rand/

Jul 21, 2016 at 11:29am
You can use the rand function and define your precision.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <time.h>

int main()
{
        srand(time(NULL));     //This makes your "rand" function generate a different number every time the program is run

        float x;
        x= 0.01 * rand()%100;  // This gives to numbers after the decimal

        if( (rand()%2 == 1)     //This is..
                x*= -1;               //..for a 1/2 chance of ending up being negative
        return 0;
}
Last edited on Jul 22, 2016 at 7:40am
Jul 21, 2016 at 11:57am
This, my very ideal function will be very useful to you :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <cmath>
double random_d()
 {
     static bool need_random = true;

    if(need_random)
    {
        srand(static_cast<unsigned int>( time(NULL)) );
        need_random = false;
    }

    int n = (rand() % 12) + 1;
    if((rand() % 100) >= 90) n = 1;
    double a = 0;
    double b = 0;
    for(long long i = 0, j = 0; i < n; i++)
    {
        j = (rand() % 10);
        b = b * 10 + j;
    }
    std::streamsize input_precision = n;
    a += (b / std:: pow(10, input_precision));

    if((rand() % 100) >= 60) a = (-a);
    return a;
 }


And in your function main(), just call :
cout << random_d();
Jul 21, 2016 at 12:11pm
@closed account 5a8Ym39o6 (300)

> Does that help you? :)

No, read FurryGuy's post more carefully.

This, my very ideal function will be very useful to you :


Neither of those.
Jul 21, 2016 at 12:11pm
Remember to use cout.setf() && cout.setprecision() or the output will be very likely truncated :
1
2
cout.setf(ios::fixed);
cout.precision(5);


Now you can call your random_d() function again :
cout << random_d();
Last edited on Jul 21, 2016 at 12:11pm
Jul 21, 2016 at 12:24pm
And better yet, to make sure std::cout prints a decimal with full precision and not printing redundant zero digits after a double (in some cases), use this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <sstream>
std::streamsize precision_d(double d)
 {
     std::stringstream ss;

     ss.setf(std::ios::fixed);

     double d2;
     std::streamsize d_precision = 0;
     for(int i = 0; i <= 20; i++)
     {
        ss.precision(i);    
        ss << d;
        ss >> d2;
        if(d == d2) break;
  
       d_precision += 1; 
       ss.str(""); ss.clear();
     }
     return d_precision;
 }


And in your code (function main()), you do the following :
1
2
3
4
5
6
7
8
9
 cout.setf(ios::fixed); // You do it only once

 double x = random_d();
 cout.precision(precision_d(x)); // Always do this before printing!
 cout << x << endl;

 double y = random_d();
 cout.precision(precision_d(y)); // Always do this before printing!
 cout << y << endl;
Last edited on Jul 21, 2016 at 12:32pm
Jul 21, 2016 at 12:25pm
Does that help you? :)
Jul 21, 2016 at 12:28pm
@TheIdeasMan
Had you tested my function very carefully, you would really not have said that.
Jul 21, 2016 at 12:37pm
@muon444
I have just changed my example to x and y to your desire.

Now everything is ready to use!!
Jul 21, 2016 at 1:01pm
Had you tested my function very carefully, you would really not have said that.


I am not saying it doesn't work, I am saying it is overkill, With C++ library <random> one can create a random number in a few LOC. Look at the example here, the same one FurryGuy linked:

http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution

Failing that, it's easy to use rand to create a sufficiently large number, then divide that by a power of 10 to achieve a double in the required range in a few LOC.
Jul 21, 2016 at 4:02pm
closed account (E0p9LyTq)
Using <random> is harder than using rand()?!?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <random>
#include <iostream>

int main()
{
   std::random_device rd;
   std::mt19937 gen(rd());
   std::uniform_real_distribution<> dis(-1.0, 1.0);
   
   std::cout << "How many random coordinates to generate? ";
   int num = 0;
   std::cin >> num;
   std::cout << "\nX:\t\tY:\n";
   std::cout << "===\t\t===\n";
   
   for (int n = 0; n < num; ++n) 
   {
      std::cout << dis(gen) << '\t' << dis(gen) << '\n';
   }
}


How many random coordinates to generate? 5

X:              Y:
===             ===
0.814205        0.896667
0.489227        -0.235508
-0.854077       0.23165
0.348448        -0.29654
0.442815        -0.503362
Last edited on Jul 21, 2016 at 4:03pm
Jul 21, 2016 at 6:10pm
Using rand() is harder than using <random>?!?

Me too. I can't afford to lose this time which is why I participate :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>

std::streamsize precision_d(double d)
 {
     std::stringstream ss;

     ss.setf(std::ios::fixed);

     double d2;
     std::streamsize d_precision = 0;
     for(int i = 0; i <= 20; i++)
     {
        ss.precision(i);    
        ss << d;
        ss >> d2;
        if(d == d2) break;
  
       d_precision += 1; 
       ss.str(""); ss.clear();
     }
     return d_precision;
 }

double random_d()
 {
     static bool need_random = true;

    if(need_random)
    {
        srand(static_cast<unsigned int>( time(NULL)) );
        need_random = false;
    }

    int n = (rand() % 12) + 1;
    if((rand() % 100) >= 95) n = 1;
    double a = 0;
    double b = 0;
    for(long long i = 0, j = 0; i < n; i++)
    {
        j = (rand() % 10);
        b = b * 10 + j;
    }
    std::streamsize input_precision = n;
    a += (b / std:: pow(10, input_precision));

    if((rand() % 100) >= 65) a = (-a);
    return a;
 }

int main()
{
   std::cout << "How many random coordinates to generate? ";
   int num = 0;
   std::cin >> num;
   std::cout << "\nX: \t\tY: \n";
   std::cout << "===\t\t===\n";

   std::cout.setf(std::ios::fixed);
   std::cout.precision(6);
   for (int n = 0; n < num; ++n) 
   {
      std::cout << random_d() << '\t' << random_d() << '\n';
   }
}


X: 		Y:  
=== 		===
0.944241 	-0.383500
-0.910700 	0.852000
0.193400 	0.811800
0.575338 	-0.534876
0.200000 	0.440487
Jul 21, 2016 at 6:13pm
closed account (E0p9LyTq)
You've bloated the size of the code, and used a very inefficient random engine. Even the C standard recommends NOT using rand(). See the C11 standard, note 295.

I'll continue using better tools designed for C++, not ancient C.
Jul 21, 2016 at 6:17pm
Does that help you? : )
Jul 21, 2016 at 9:26pm
closed account, random_d() doesn't give you a uniform distribution.
Jul 21, 2016 at 10:09pm
> closed account, random_d() doesn't give you a uniform distribution.
Then what exactly is a "uniform distribution"?
Jul 21, 2016 at 10:49pm
closed account (E0p9LyTq)
Then what exactly is a "uniform distribution"?

Something the C library random functions do not produce, never have and never will.
http://statistics.about.com/od/ProbHelpandTutorials/a/What-Is-A-Uniform-Distribution.htm
http://stattrek.com/statistics/dictionary.aspx?definition=uniform_distribution

closed account wrote:
I can't afford to lose this time which is why I participate

Woodrow Wilson said it best:

"You lose".
Last edited on Jul 21, 2016 at 11:16pm
Jul 22, 2016 at 1:30am
But as long as it does the job the OP wants...isn't it nice?

> I need to have my coordinate must lie with in -1 < x < 1 and -1 < y < 1.

The OP did not say the random numbers MUST be generated using a "uniform distribution". At least, it is the thing that we know.
Jul 22, 2016 at 2:08am
closed account (E0p9LyTq)
Neither did they say the numbers couldn't be uniformly distributed, and if there is a choice why go with something less than optimal?

Being sloppy is being sloppy.

Poor random number generation is sloppy, and that is rand().

The entire idea of RANDOM numbers is to NOT be predictable. rand() is predictable.

If rand() is so great, then why is the C standard (C11) recommending it NOT be used?
Last edited on Jul 22, 2016 at 2:12am
Pages: 12