rand # only for odd #

Hi C++ ,
I have program for 5 random numbers from 1 to 10 .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
srand(time(0)); 
	int num;

	while (cin)
	{
		cout << " 5 random #  1 - 10 --->   ";
		for (int x = 1; x < 6; x++)
		{
			cout << 1 + (rand() % 10) << " ";
		}

		cout << " \n\n for continue press (2)  " << endl;
		cout << " for stop program press  (-1) " << endl;
		cin  >> num;
		if (num == -1)
		{
			break;
		}
		else
		{
			continue;
		}
	}  


I want to select evens numbers that program will ignore .
I want random numbers only for odd numbers .
Is it possible ? pls let me know , thanks P.
Last edited on
1+2*(rand()%5)
If you are going to write C++ code avoid using rand/srand. Use the C++ random number/time libraries instead. <random>/<chrono>.

https://web.archive.org/web/20180123103235/http://cpp.indi.frih.net/blog/2014/12/the-bell-has-tolled-for-rand/
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
It was fast :) Thanks ..
I was just curious how can I do it ..
If I want ignore just number 4 and 7 how can I do it ?
Perform a loop. Generate a random number. Increment the loop when the number is NOT 4 or 7.

See my first link for the basics.
Thanks
Note that using % results in distributions that are not perfectly uniform due to the pigeon-hole principle. I think Lavavej mentions this in his talk.

But assuming that you do have access to a uniform distribution source, if you are trying to exclude M particular solutions from your distribution of size N, one sort of simple way is to generate a distribution of size (M - N), and then skip over the excluded numbers when doing the mapping. This would allow you to still just make a single random call per trial. But each mapping takes O(M) to compute. For large M, using a std::map would be preferable as that would be O(log(M)) per trial.

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
// Example program
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

int distribution_with_exclusions(const int Range, const int Exclusions[], const int NumExclusions)
{
    const int RollSize = Range - NumExclusions;
    int roll = rand() % RollSize + 1; // note: +1 here because OP was doing 1-based ranges, e.g. [1, 10]
    // Also, warning: Like I said, rand()%N is inherently NOT uniform for most values of N
    
    int offset = 0;
    for (int i = 0; i < NumExclusions; i++)
    {
        if (roll + offset >= Exclusions[i])
        {
            offset++;
        }
    }

    return roll + offset;
}

int main()
{  
    const int N = 10;
    const int M = 2;  
    const int exclusions[M] = {4, 7}; // (note: will be 1-based)

    // output distribution, including the zeroed out numbers
    int output_dist[N] {};

    for (int i = 0; i < 100000; i++)
    {
        int roll = distribution_with_exclusions(N, exclusions, M); // still 1-based!
        if (roll - 1 < 0 || roll - 1 > N - 1)
            std::cout << "error: Role out of bounds of expected distribution!\n";
        
        output_dist[roll - 1]++;
    }
    
    for (int i = 0; i < N; i++)
    {
        // +1 here is because OP did 1-based distribution.
        std::cout << (i+1) << " : " << output_dist[i] << '\n';
    }
}

Nothing excluded:
1 : 10072
2 : 10005
3 : 9954
4 : 10132
5 : 10007
6 : 10045
7 : 9869
8 : 9959
9 : 9953
10 : 10004

{4, 7} excluded:
1 : 12503
2 : 12437
3 : 12474
4 : 0
5 : 12608
6 : 12446
7 : 0
8 : 12777
9 : 12432
10 : 12323

{4, 8} excluded:
1 : 12503
2 : 12437
3 : 12474
4 : 0
5 : 12608
6 : 12446
7 : 12777
8 : 0
9 : 12432
10 : 12323


I think the math works out here. Or, use the C++11 <random> libraries, which, while more verbose, offer a wider solution of random distributions and aren't based off rand().

Edit: Actually, each trial could be O(1) constant time if you pre-computed an offset table for each possible value of the distribution. e.g. {0, 0, 0, 1, 1, 2, 2, 2, 2, 2}.
Last edited on
I didnt follow all that, but if you just want odd numbers:

whatever = something;
whatever |=1; //force it to be odd. (this is similar to what lastchance did)
this may need you to subtract 1 from your limt, eg if you want 1-10 and not 11, you instead should do 1-9 so that 10 is not rolled and bumped up to 11....
I don't know if this messes with your distribution count etc. Is that critical to you?
Last edited on
@Ganado,
Those are some fancy stochastical machinations there!
But you forgot the srand(time(nullptr)). ;-)
Registered users can post here. Sign in or register to post.