Thread: Why is the output of this wrong?

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    9

    Why is the output of this wrong?

    It doesn't output the proper number of pseudorandom numbers. Well, sometimes it does and sometimes it doesn't.

    One example can be seen when you enter 9 at the first prompt and 8 at the second. Or 8 at the first and 3 at the second.

    Code:
    #include <iostream> //opens iostream as a standard C++ included file
    #include <conio.h> //opens conio.h for use of getch() and system() commands
    #include <ctime> //opens ctime for the seeding of rand() using time
    #include <cstdlib> //opens cstdlib for rand() function
    #include <algorithm> //opens algorithm for sort() function
    #include <set> //opens set for the use of sets
    
    using namespace std; //uses the standard C++ namespace
    
    int main() //opens the main (and only) function
        {
             int maxnum; //sets the variable "maxnum" (the highest random number that will be displayed) as an integer
             int numofnums; //sets the variable "numofnums" (the number of random numbers that will be displayed) as an integer
             int watcher; //sets the variable "watcher" (counter) as in integer
             int endopt; //sets the variable "endopt" (option to repeat the program or exit the program) as in integer
             int i; //sets the variable i as an integer, but i is gone now, I think
             int randnum; //sets the variable "randnum" (used to add a random number into the set) to and integer
    
             srand(time(0)); //seeds rand() by using the system time; exact outcome is based on OS
    
             cout << "Welcome to the Random Number Generator." << endl;
             cout << "Press any key to continue." << endl;
             getch(); //pauses the program until the user hits any key
             system("cls"); //a system call to clear the screen
    
                       step1:
    
                       maxnum = 0;
                       numofnums = 0;
                       watcher = 0;
                       endopt = 0;
                       i = 0;
                       randnum = 0;
    
                                 cout << "Enter the maximum number in your range of random numbers." << endl;
                                 cout << "This number will be the highest possible number that can be output." << endl;
                                 cin >> maxnum;
    
                                 while (maxnum <= 1) //an error check for an invalid maximum number (maxnum)
                                      {
                                           system("cls"); //a system call to clear the screen
                                           cout << "\aYou entered an invalid number." << endl;
                                           cout << "The highest possible number must be greater than 1." << endl;
                                           cout << "Please try again. Enter the highest possible random number." << endl;
                                           cin >> maxnum;
                                      }
    
                                 system("cls"); //a system call to clear the screen
                                 cout << "Enter the number of random numbers to display." << endl;
                                 cout << "This will be the number of random numbers that you will see." << endl;
                                 cin >> numofnums;
    
                                 while (numofnums <= 0) //an error check for an invalid number of random numbers
                                      {
                                           system("cls"); //a system call to clear the screen
                                           cout << "\aYou entered an invalid number." << endl;
                                           cout << "The number of displayed numbers must be greater than 0." << endl;
                                           cout << "Please try again. Enter the number of random numbers to display." << endl;
                                           cin >> numofnums;
                                      }
    
                                 if (numofnums >= maxnum)
                                      {
                                           cout << "You entered invalid numbers." << endl;
                                           cout << "To prevent double or triple numbers, the range of the random numbers \n must be greater than the total number of random numbers displayed." << endl;
                                           cout << "Press any key to try again." << endl;
                                           getch(); //a "pause" command
                                           system("cls"); //a system call to clear the screen
                                           goto step1; //brings the user back to the beginning to try again...might replace this goto in the future
                                      }
    
                                  else
                                      {
                                           set<int, less<int> > randSet; //creates the set
                                           watcher = 0; //sets the counter to 0 to prevent problems
    
                                           while (watcher < (numofnums))
                                                {
                                                     randnum = (rand() % (maxnum + 1));
    
                                                     randSet.insert(randnum); //fills the set with values
                                                     watcher = watcher + 1; //adds one to "watcher", which is the counter
                                                }
    
                                           cout << "Your random numbers are..." << endl;
    
                                           set<int>::iterator iter;
    
                                           for (iter = randSet.begin(); iter != randSet.end(); iter++)
                                                cout << *iter << endl;
    
                                           do
                                                {
                                                     cout << "\n"; //newline
                                                     cout << "Enter 1 to run again or 2 to exit." << endl;
                                                     cin >> endopt;
                                                     system("cls"); //a system call to clear the screen
    
                                                     switch (endopt)
                                                          {
                                                               case 1:
                                                               goto step1;
                                                               break;
    
                                                               case 2:
                                                               return 0;
                                                               break;
                                                            }
                                                }
                                           while (endopt != 1 && endopt != 2);
                                      }
        }

  2. #2
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    Code:
    goto step1;
    Theres your problem, right there.


    Kidding aside, This quote comes from the visual studio.NET documentation for the set container (emphasis added by me):

    The STL container class set is used for the storage and retrieval of data from a collection in which the values of the elements contained are unique and serve as the key values according to which the data is automatically ordered.

    This means that the values put into the set MUST be unique.

    Code:
    randnum = (rand() % (maxnum + 1));
    Can you guarentee that this will always return a unique value every time you use it? Certainly not, it wouldn't be a very good random number generator if it didn't ever return a duplicate value.

    Your error is when rand % whatever does end up returning a dupe, in which case your insertion into the set gets ignored.

    A better bet than using the watcher variableas a counter is to continue inserting random numbers until randSet.size() is equal to numofnums.

    this:

    Code:
    while (watcher < (numofnums))
    becomes:

    Code:
    while(randSet.size() <= numofnums)
    I came up with a cool phrase to put down here, but i forgot it...

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by ...
    Code:
    while(randSet.size() <= numofnums)
    Not quite... when randSet.size() returns numofnums, meaning we have exactly the number of elements in the set that we require, the loop would still execute at least once more and we will end up having numofnums+1 elements in the set. You still need to use < and not <=.

    That said, this section of code:

    Code:
    set<int, less<int> > randSet; //creates the set
    watcher = 0; //sets the counter to 0 to prevent problems
    
    while (watcher < (numofnums))
    {
        randnum = (rand() % (maxnum + 1));
    
        randSet.insert(randnum); //fills the set with values
        watcher = watcher + 1; //adds one to "watcher", which is the counter
    }
    Can simply be rewritten as:

    Code:
    set<int> randSet;  // The less<int> is assumed as a default
    while( randSet.size() < numofnums )
        randSet.insert(rand()%(maxnum+1));
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    My mistake.

    I didn't sleep last night, and for some reason that seemed right at the time. :\
    I came up with a cool phrase to put down here, but i forgot it...

  5. #5
    Registered User
    Join Date
    Nov 2004
    Posts
    9
    So I was on the right track, with my error preventing earlier in the code. I just didn't carry it into the set.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Whats wrong with the Output?
    By shabbirhussain in forum C Programming
    Replies: 5
    Last Post: 08-26-2008, 08:28 AM
  2. Wrong Output!
    By kolliash in forum C++ Programming
    Replies: 6
    Last Post: 06-19-2008, 07:55 AM
  3. Something Wrong with my function in Linux!
    By Matus in forum C Programming
    Replies: 5
    Last Post: 04-30-2008, 10:00 PM
  4. Getting wrong output from a class
    By orikon in forum C++ Programming
    Replies: 11
    Last Post: 11-18-2005, 07:58 PM
  5. Leap year program prints wrong output
    By Guti14 in forum C Programming
    Replies: 8
    Last Post: 08-24-2004, 11:56 AM