I'm new to the C++ world, (first quarter intro to C++) and am trying to write a small simple program in school that uses the random number generator function in the standard library to generate a random sequence of letters from A to Z(ascii 65-91). How can I set the range of the random function to generate random numbers between 65 and 91 I understand how to cast them into a character, but as the program sits now, I keep getting random characters and few, if any, letters.

beginning c++
Michal Malecki - MSFT
There are creative ways to use up all 15 bits that rand() sets in order to make the distribution more even. You could for instance, "blend" the bits, 3 groups of 5 bits each--this will be a 5-bit quantity in the range 0-31. Keep repeating this until you get a number in the 0-25 range. (This way we aren't mapping 26-31 to any of the 26 letters, causing unevenness.).
assert( RAND_MAX == 32767 ); // just in case i'm wrong about RAND_MAX
int result;
do
{
int n = rand();
result = ((n >> 10) & 0x1f) ^ ((n >> 5) & 0x1f) ^ (n & 0x1f);
} while( result >= 26 );
char c = (char)result + 'A';
For the various operators I've used here, you should be able to find them in the documentation, and of course in any C++ book. (Why wait until it's covered in class :))
I ran this 1,000,000 times and tallied the frequencies, and the results look fairly even. 1/26 = 0.0384615...
65 38554 0.038554
66 38412 0.038412
67 38527 0.038527
68 38699 0.038699
69 38084 0.038084
70 38426 0.038426
71 38206 0.038206
72 38662 0.038662
73 38577 0.038577
74 38318 0.038318
75 38511 0.038511
76 38360 0.03836
77 38189 0.038189
78 38494 0.038494
79 38646 0.038646
80 38725 0.038725
81 38516 0.038516
82 38069 0.038069
83 38849 0.038849
84 38742 0.038742
85 38276 0.038276
86 38295 0.038295
87 38511 0.038511
88 38395 0.038395
89 38684 0.038684
90 38273 0.038273
Brian
caaptain
Thanks, I was ready to get into a fist fight with this thing. I've only been taking C++ for about 6 weeks now, and in that lab for school, my book only vaguely described the usage of the random function. This is the short program I was working on, once again, thanks for your help!
#include <iostream.h>
#include <stdlib.h> //for random
#include <iomanip.h> //for setw
void get_a_letter(int);
int main()
{
int seed;
char answer='y';
while(answer=='y')
{
cout<< "\n Please enter integer value for seed.";
cin>>seed;
srand(seed);
get_a_letter(seed);
cout<< "\n Would you like to see more random letters ";
cin>> answer;
}
cout<<endl;
return 0;
}
void get_a_letter(int seed)
{
int letter_ctr, rand_num, abc;
for(letter_ctr=0; letter_ctr<15; ++letter_ctr)
{
rand_num=rand()%26+65;
abc=char(rand_num);
cout << "\n " << letter_ctr+1<< setw(5) << (char)abc;
}
}
Ofer Gal
The modulo operator does its work but it has the drawback that the sequences of random numbers are not evenly distributed.
This is no problem if the range you need is far less than RAND_MAX.
Example: In the case the range is is from 0 to RAND_MAX*2/3 you get the problem that the lower 1/3 range of numbers are choosen twice as often as the upper 2/3.
Anwar Javed
You can the % (modulo) operator to constrain the result of rand() to a range (0 through 25 = 26 values), and then add an offset (65).
int randnum = rand() % 26 + 65;
char mychar = (char)randnum;
Jmill07
An easy way to make sure each integer in your set has the same number of rand() results mapped to each is to just dissallow results from the top incomplete set:
const int LO = 65, HI = 90;
const int MY_RAND_MAX = RAND_MAX - (RAND_MAX + 1) % (HI - LO + 1);
int randomInt;
do {
randomInt = rand();
} while(randomInt > MY_RAND_MAX);
randomInt = randomInt % (HI - LO + 1) + LO;
Really, the same thing Brian is doing.
jcbrooks75
@wooten
Beside all problems and the evency of rand, the main problem is the modulo operation itself. rand gives a random nimber from 0 up to 0x7fff. So it uses 15bits (hopefully evenly distributed).
The module is nothing else then the left over of a division. So the modulo breaks the hole sequence of numbers into sub sequences from A to Z.
So starting at
0-25 its the first sequence of A-Z
26-51 is the second sequence
52-77 is the third sequence
this continus at a total 1260 times up to the
32760-32767
You see that there is no longer a full seqence. So if the modulo is not taken from a power of 2 number the random number seuqnece is not evenly distributed.
And you can see that the lower 7 chars (A,B,C,D,E,F,G) choosen 1/1260 more often.
HTH
Jaewon