C++ Random Number Causing Crash when printing out value only. Very strange - c++

I need a value between 0.0 and 1.0. So I seed the random number generator using time. Then I get a value between 0 and 10 using the rand function. After that I take that value and divide it by 10 to get my decimal value. My issues is that the program will randomly crash when I try and print out the value generated by (dRandNum % 10). Also of note is that it is not crashing in the middle of the for loop. It's always right at the beginning on the first attempt to print out. I'm honestly thinking that there's just something really strange with the compiler and was wondering if anyone could direct me otherwise.
double dRandNum = 0;
int tempRand = 0;
/* initialize random seed: */
srand ( (unsigned)time(0) );
for(int i = 0; i < 40; i++)
{
tempRand = rand();
cout << "tempRand= " << tempRand << endl;
dRandNum = tempRand % 10;// + 1;
// Crashes here for some reason. If I don't try and print the value it's fine
cout << "Random Num Before " << i << ": " << dRandNum << endl;
dRandNum = dRandNum / 10;
cout << "Random Num After " << i << ": " << dRandNum << endl;
weights[i] = dRandNum;
}

OK, I'm going to take a random stab here and ask you to show us the declaration of the weights[] array.
And I'll even wager the traditional virtual jelly doughnut that weights[] is not declared to hold 40 elements.

For the sake of the program one can assume the function is wholly independent
That's a big mistake, it never is. This has heap corruption written all over it. Which rarely causes a crash at the line of the code that corrupts the heap. Always later, sometimes much later.

Related

Having garbage numbers while calculating percentage

So, I hate to ask, but, I'm having some issue with this, I'm new to C++ and I'm just starting out. Everything is done for the most part. Expect for a little thing.
Line 35-36 should be calculating the average (Which for some reason, I haven't been able to get it to work.)
Line 41-47 should print out the percentage that heads/tails was landed on with precision to one decimal, and then print out the correct numbers of * to represent the percentage.
But, when I run it, my heads/tail count is messed up. As well as my percentage numbers. I'm just looking for a push in the right direction.
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <iomanip>
using std::cout; using std::cin; using std::endl;
using std::fixed; using std::setprecision;
int main()
{
srand(time(0));
int userInput,
toss,
headsCount,
tailsCount;
double headsPercent = 0,
tailsPercent = 0;
cout << "How many times do you want to toss the coin? ";
cin >> userInput;
while(userInput < 0)
{
cout << "Please enter a positive number: ";
cin >> userInput;
}
for(int i = 1; i < userInput; i++)
{
toss = rand() % 2;
if(toss == 0)
headsCount++;
else
tailsCount++;
}
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
cout << "Heads: " << headsCount << endl
<< "Tails: " << tailsCount << endl << endl;
cout << "Heads Percentage: " << fixed << setprecision(1) << headsPercent << " ";
for(int b = 0; b < headsPercent; b++)
cout << "*";
cout << "\nTails Percentage: " << tailsPercent << " ";
for(int b = 0; b < tailsPercent; b++)
cout << "*";
return 0;
}
In addition to the uninitialized variables here, that others have pointed out, the calculations are all wrong.
Take out paper and pencil, and run some your own calculations the old-fashioned way.
Let's say there were five tosses, three heads, two tails. This means that (after fixing the uninitialized variables):
userInput=5
headsCount=3
tailsCount=2
Now, here's how you're calculating your supposed percentages:
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
So, using your own numbers, you will get:
headsPercent = 5 / 3 * 100
tailsPercent = 5 / 2;
Does this look right to you? Of course not. You can do the arithmetic yourself. Divide 5 by 3 and multiply by 100. This is integer division, so five divided by three is 1, multiplied by 100 is 100. Five divided by two is two. So you get 100% and 2% here.
Of course, that's wrong. Two and three times, out of five, is 40% and 60%, respectively.
Writing a program means:
A) Figure out how calculations need to be made
B) Write the code to do the calculations.
You're still on step A. You need to figure out how you want to make these calculations so they're correct, first.
This has nothing really to do with C++. If you were using any other language, and coded this, in that manner, you'll get the same wrong answers.
The only thing this might have to do with C++ is that integer division, in C++ does not produce a fractional amount. It's integer division. But that's not your only problem.
Firstly u have to correct ur basics of mathematics.
Calculating %age means
example
(Marks obtained)/(Total marks)*100
Not (Total marks/marks obt)*100
Dividing any no by 0 is not defined. So if ur current code randomly assign toss or head =0, then obviously u will have errors.
Secondly talking about codes, U should either initialize i from 0 , or u should use
for (i=1; i<=userInput; i++)
As otherwise the head+toss value will be userInput-1.
Also remember to initialise variables like
Int headsCount=0;
etc. As the variable will take any random value if not initialised to a fixed no. (Though it does not creates a problem here)
And just change the datatype
int userInput,
toss,
headsCount,
tailsCount;
To
double userInput,
toss,
headsCount,
tailsCount;
This will solve your problem.
Advice: Please use
using namespace std;
in the starting of ur programs as u have to type a lot of std::
Welcome to C++. You need to initialise your variables. Your compiler should have warned you that you were using a variable without initialising it. When you don't initialise a value, your program has undefined behaviour.
I'm talking about headsCount and tailsCount. Something like this should be fine:
int headsCount = 0, tailsCount = 0;
Also note that your loop should start at 0, not 1, since you are using the < operator on the final condition.
Finally, your percentage calculations are backwards. It should be:
headsPercent = headsCount * 100 / userInput;
tailsPercent = tailsCount * 100 / userInput;
Now, there's a weird thing that might happen because you are using integer division. That is, your percentages might not add up to 100. What's happening here is integer truncation. Note that I dealt with some of this implicitly using the 100x scale first.
Or, since the percentages themselves are double, you can force the calculation to be double by casting one of the operands, thus avoiding integer truncation:
headsPercent = static_cast<double>(headsCount) / userInput * 100;
In fact, since the only two possibilities are heads and tails, you only need to count one of them. Then you can do:
tailsPercent = 100 - headsPercent;
1) This loop should start from 0:
for(int i = 1; i < userInput; i++)
2) The divisions are not correct:
//headsPercent = userInput / headsCount * 100;
//tailsPercent = userInput / tailsCount;
headsPercent = headsCount / userInput * 100;
tailsPercent = tailsCount / userInput * 100;
3) Finally:
cout << "\nTails Percentage: " << fixed << setprecision(1) << tailsPercent << " ";

Program will not output data to console when using a data input size greater than 30 million

I'm trying to make a program that will eventually show the runtime differences with large data inputs by using a binary search tree and a vector. But before I get to that, I'm testing to see if the insertion and search functions are working properly. It seems to be fine but whenever I assign SIZE to be 30 million or more, after about 10-20 seconds, it will only display Press any key to continue... with no output. However if I assign SIZE to equal to 20 million or less, it will output the search results as I programmed it. So what do you think is causing this problem?
Some side notes:
I'm storing a unique, (no duplicates) randomly generated value into the tree as well as the vector. So at the end, the tree and the vector will both have the exact same values. When the program runs the search portion, if a value is found in the BST, then it should be found in the vector as well. So far this has worked with no problems when using 20 million values or less.
Also, I'm using randValue = rand() * rand(); to generate the random values because I know the maximum value of rand() is 32767. So multiplying it by itself will guarantee a range of numbers from 0 - 1,073,741,824. I know the insertion and searching methods I'm using are inefficient because I'm making sure there are no duplicates but it's not my concern right now. This is just for my own practice.
I'm only posting up my main.cpp for the sake of simplicity. If you think the problem lies in one of my other files, I'll post the rest up.
Here's my main.cpp:
#include <iostream>
#include <time.h>
#include <vector>
#include "BSTTemplate.h"
#include "functions.h"
using namespace std;
int main()
{
const long long SIZE = 30000000;
vector<long long> vector1(SIZE);
long long randNum;
binarySearchTree<long long> bst1;
srand(time(NULL));
//inserts data into BST and into the vector AND makes sure there are no duplicates
for(long long i = 0; i < SIZE; i++)
{
randNum = randLLNum();
bst1.insert(randNum);
if(bst1.numDups == 1)//if the random number generated is duplicated, don't count it and redo that iteration
{
i--;
bst1.numDups = 0;
continue;
}
vector1[i] = randNum;
}
//search for a random value in both the BST and the vector
for(int i = 0; i < 5; i++)
{
randNum = randLLNum();
cout << endl << "The random number chosen is: " << randNum << endl << endl;
//searching with BST
cout << "Searching for " << randNum << " in BST..." << endl;
if(bst1.search(randNum))
cout << randNum << " = found" << endl;
else
cout << randNum << " = not found" << endl;
//searching with linear search using vectors
cout << endl << "Searching for " << randNum << " in vector..." << endl;
if(containsInVector(vector1, SIZE, randNum))
cout << randNum << " = found" << endl;
else
cout << randNum << " = not found" << endl;
}
cout << endl;
return 0;
}
(Comments reposted as answer at OP's request)
Options include: compile 64 bit (if you're not already - may make it better or worse depending on whether RAM or address space are the issue), buy more memory, adjust your operating system's swap memory settings (letting it use more disk), design a more memory-efficient tree (but at best you'll probably only get an order of magnitude improvement, maybe less, and it could impact other things like performance characteristics), redesign your tree so it manually saves data out to disk and reads it back (e.g. with an LRU).
Here's a how-to for compiling 64 bit on VC++: msdn.microsoft.com/en-us/library/9yb4317s.aspx

Finding the smallest number and largest number from a list of random numbers generated

I'm new here and this forum has been a great help! Unfortunately, I'm not able to find the answer to my issue here or anywhere else on the web. I was hoping some of you can give me some help or tips on how to go about this.
The program will generate random numbers based on the max limit and the amount of random numbers that will generate.
I'm also required to find the smallest, largest number, as well as the average from all the numbers generated in the loop. The average I can find using the sum/MAX_COUNT_NUM. Unfortunately, I am stuck finding the smallest and largest number. Been at this for the past 6 hours. Please help anyway you can. Thank you.
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <iomanip>
using namespace std;
int main(){
int UP_MAX, MAX_COUNT_NUM, RAND_NUM, MIN_COUNT_NUM;
cout << "This program creates random numbers" << "\n" << "\n";
cout << "Enter the upper limit of all generated random numbers: ";
cin >> UP_MAX;
cout << "\n" << "\n";
cout << "Enter the count of random numbers: ";
cin >> MAX_COUNT_NUM;
cout << "\n" << "\n";
cout << "Creating " << MAX_COUNT_NUM << " random numbers from 1 to " << UP_MAX << ": " << "\n" << "\n";
MIN_COUNT_NUM = 1;
int LARGE = 0;
int SMALL = 0;
for (; MAX_COUNT_NUM >= MIN_COUNT_NUM; MIN_COUNT_NUM++)
{
RAND_NUM = rand() % UP_MAX + 1;
cout << setw(8) << RAND_NUM;
if (RAND_NUM < SMALL)
{
SMALL = UP_MAX + 1;
}
if (RAND_NUM > LARGE)
{
LARGE = RAND_NUM;
}
}
Unfortunately, I need to do this without arrays and vectors. In my head, I'm thinking it should work as well but it doesn't. The largest number comes out fine, but the smallest comes out as 0 which makes me scratch my head.
I'm taking a beginners course and this got me stumped, so my way of thinking may be off beat. If there are any other tips you can provide, I definitely appreciate it.
The problem is with the initial values that you picked for LARGE and SMALL: you set both of them to 0, which is incorrect: you should set them both to the first random number that you generate.
Alternatively, you can set SMALL to the largest possible int, and LARGE to the smallest possible int. Use <limits> header and std::numeric_limits<int> class.
Note: SMALL = UP_MAX + 1; should be SMALL = RAND_NUM;

C++ Random number generator, isnt random but always returns the same number

Hi im looking for RandNum to generate a number between 2-10, and then that number being taken away from 15.
Right now, every time the program is executed, the number taken away from 15, (PerseusHealth) is 7. How do i fix this, and make it random?
void desertpath()
{
int scorpianchoice; //the option the player chooses.
int Maxhit = 10; //Max hit the scorpian can do
int Minhit = 2; //Min hit the scorpian can do
int randNum = rand()%(Maxhit + Minhit) + Minhit;
int healthremaining = PerseusHealth - randNum; //health left in option1.
if(scorpianchoice == 1)
{
cout << "You run under the Scorpians Legs in hopes to escape " << endl;
cout << "You are hit by the scorpians Sting for " << randNum << " hp!";
cout << "You have " << healthremaining << "/15 HP Left!" << endl;
cout << "You escape the Scorpian but not without taking some damage" << endl;
}
Use srand to initialize.
srand((unsigned)time(0));
Also, I think you have not put the brackets correctly:
int randNum = (rand()%(Maxhit - Minhit)) + Minhit;
Clarification on top of #ebad86 answer
rand() is known for bad quality, especially when low bits are used. Most likely, for example, output is always generated with low bit set to 1. Simple solution might be to use bits from the middle of the sequence by shifting bits (say, by 8)
If max generated output of rand() is not divisible by (Maxhit-Minhit), you'll get (slightly) biased result. It might be ok for your purposes, but you'd better know it

2nd call of srand() in the same program with the same seed is NOT producing the same values for successive rand()

I'm working on a simple "addition questions" program for my intro to C++ class. My instructor uses a test driver to grade our code. The test driver first runs the program using his code, and then runs my function and compares the two.
In this code, we're supposed to generate random numbers to give the user simple addition problems. They enter the answer and the program keeps track of how many they got correct, and returns the number of correct answers to the main function.
As I understand it, srand() will generate the same list of numbers if the seed is the same. The problem I'm having is even though I put srand(seed) at the top of my function, the successive numbers generated by each rand() call are still different. As I understood it, if you recall srand with the same seed, it will reset the number generator and give you the same chain of numbers from rand().
Because he uses a test driver to grade, the driver is telling me almost all of my results are wrong, but it's because the driver does not actually calculate my random generated numbers, it just looks for the same answers as what he got in his version of the program. So the problem is for some reason calling srand(seed) is not using the same numbers.
This could be a problem with his driver, if it is sending a different number to my function for seed than he used, but it could also be that I put srand() in the wrong place, or I'm not using it correctly.
Can anyone confirm if the use of srand(seed) in my code would reset and use the same numbers given that seed value is the same?
Here's my function:
int correct = 0; // initialize global variable to return correct answers
// define the additionQuestions function.
int additionQuestions(int largest, int problemCount, int seed)
{
srand(seed); // initialize the random generator to the same seed used in test driver
int gen1, gen2, answer;
bool quitting = false;
// generate problems
for (int count = 0; count < problemCount && (!(quitting)); count++)
{
gen1 = rand() % largest;
gen2 = rand() % largest;
cout << "How much is " << gen1 << " plus " << gen2 << "? ";
cin >> answer;
if (answer == -1) // check for sentinel of -1
{
cout << endl << " You entered -1; exiting...";
quitting = true;
}
else // check if the user's answer is correct.
{
cout << endl << " You said " << gen1 << "+ " << gen2 << " = " << answer << ".";
if (answer == gen1 + gen2)
{
cout << " Very good!" << endl;
correct += 1;
}
else
{
cout << " No. Sorry, the correct answer is " << gen1 + gen2 << "." << endl;
}
}
} // end of for loop.
return correct; // return the number of correct answers to the main function
}
Before you write to your professor....
Your using implicit type casting from 'int seed' to 'srand(unsigned int seed)' which could cause issues when the test driver tries to test your program with a seed larger than ~2.1M.
Good luck.