Having difficulties locating a problem in the for loop - c++

I am writing a program where a user inputs the name of contestants and buys like a ticket for a competition. I am trying to figure out the percent chance for each contestant to win but for some reason its returning zero, here's the code
for(int i = 0; i < ticPurch.size(); i++){
totalTics = ticPurch[i] + totalTics; //Figuring out total amount of ticket bought
}
cout << totalTics;
for (int i = 0; i < names.size(); i++){
cout << "Contenstant " << " Chance of winning " << endl;
cout << names[i] << " " << ((ticPurch.at(i))/(totalTics)) * 100 << " % " << endl; //Figuring out the total chance of winning
}
ticPurch is a vector of the the tickets each contestant bought and names is a vector for the contestants name. For some reason the percent is always returning zero and I don't know why
return 0;

Dividing an integer by an integer gives you an integer, by truncation of the fractional part.
Since your values are less than one, your result will always be zero.
You could cast an operand to a floating-point type to get the calculation you wanted:
(ticPurch.at(i) / (double)totalTics) * 100
Then probably round this result, since you seem to want whole number results:
std::floor((ticPurch.at(i) / (double)totalTics) * 100)
My preferred approach, which avoids floating-point entirely (always nice!), is to multiply to the resolution of your calculation first:
(ticPurch.at(i) * 100) / totalTics
This will always round down, so be aware of that if you decided to go with, say, std::round (or std::ceil) instead of std::floor in the example above. Arithmetic trickery can mimic those if needs be.
Now, instead of e.g. (3/5) * 100 (which is 0*100 (which is 0)), you have e.g. (3*100)/5 (which is 300/5 (which is 60)).

Related

how to avoid the loss of precision when trying to round number? (C++)

just finished my first week of C++(using Visual Studio 2017), I wrote a program that asks the user for the amount of money and will print the number of bills and coins. it works at the beginning, but sometimes it just prints wrong number.(when the user input $1.28, it shows 1 dollar, 1 quarter and 2 pennies.)
here is my code, is there anything wrong? the algorithm or the data type?
#include<iostream>
using namespace std;
float Q = 0.25;
float D = 0.10;
float N = 0.05;
float P = 0.01;
float Dollar = 1;
float money;
float dollars, quarters, dimes, nickels, pennies;
int main() //to break money into coins.
{
cout << "how many money do u have?" << endl;
cin >> money;
dollars = (int)money;
quarters = (int)((money - dollars*Dollar)/Q);
dimes = (int)((money - dollars*Dollar - quarters*Q) / D);
nickels = (int)((money - dollars*Dollar - quarters*Q - dimes*D) / N);
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
cout << "$" << money << " can be break into :" << endl;
cout << dollars << " dollars. " << endl;
cout << quarters << " quarters. " << endl;
cout << dimes << " dimes. " << endl;
cout << nickels << " nickels. " << endl;
cout << pennies << " pennies. " << endl;
}
how to avoid the loss of precision when trying to round number? (C++)
When you convert from floating point to integer, the fractional part is truncated. To ensure no loss of integer precision (getting the right "whole"), add 0.5 to the result each time e.g:
quarters = static_cast<int>(((money - dollars*Dollar)/Q)+0.5);
This however doesn't work when the result is negative e.g:
50.5 - 100 = -49.5 -> +1 = -48.5 -> -48... not 49
For negatives you would want to therefore subtract 0.5.
I'd assume, that in the line
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
the part (money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) will produce a value, that is not exactly .03, but a tad below. This is due to the nature of floating point arithmetic, you should read on that. Given that it's something like .029999999995, division by .01 will not yield 3.0, but maybe 2.9999999995. Since you are not rounding, but casting the value to an integer, the whole part after the period will be thrown away, hence it results in 2 pennies.
How can you solve this issue?
The simplest thing will be to round the value instead of casting it, this should yield the correct value, but this is kind of a hacky solution to an issue there is an exact solution for. You could also try to use double instead of a float, but this, too, would not solve the issue. You might get this correct, but the same a similar bug could still occur.
Store whole pennies
You could store the whole amount as an integer (whole pennies)
int amountInPennies;
int penniesPerDollar = 100;
int penniesPerQuarter = 25;
int penniesPerDime = 10;
int penniesPerNickle = 5;
int totalDollars = amountPennies / penniesPerDollar;
int totalQuarters = (amountPennies - totalDollars * penniesPerDollar) / penniesPerQuarter;
...
Decimal types
In a real world application dealing with money (well, depending on the type) you'd most likely go with some kind of decimal type instead of a float. According to this answer there are libraries with arbitrary precisions arithmetic available under the GNU license. You could still roll your own decimal type, that - more or less - does what I presented in the first approach. This might be a great excercise to learn, but maybe a ready-made library would be the better option when it comes to a real world application.

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 << " ";

Wrong result while trying to divide

To learn C++, I follow an online class and I am trying to create a console mode game.
The game take a random word, split the word and ask the user to guess the word.
When the user don't wanna play anymore and quit the game, my program show some statistics (total of game played, game wins ...).
While I am trying to get the win percentage, I get wrong result.
Explanation (What I want) :
My user win 1 game and lose 1 game -> 1/2 * 100 = 50% (win percentage)
What is wrong (What I get) :
My function return 0 for 1/2 * 100.
void gameStatistics(int gameNumber, int gameWin, int defeats, int tries)
{
std::cout << "You quit." << std::endl;
float const winpercentage=float(gameWin / gameNumber) * 100; // C4244, resolved by casting the int into float.
std::cout << "Win average: " << winpercentage << std::endl;
std::cout << "Statistics: Number of games played: " << gameNumber << " Number of win: " << gameWin << " Number of defeat: " << defeats << " Number of tries: " << tries << std::endl;
}
I have been struggling for a while and I need someone to explain what I am doing wrong.
Thanks in advance
1/2 = 0 in integer logic.
1/2.0f = 0.5f in float logic.
This line float(gameWin / gameNumber) means that divide in integer space then convert the result to float space.
You should do this:
float(gameWin) / gameNumber
or even better:
static_cast<float>(gameWin)/ gameNumber
When you do float(gameWin / gameNumber) the division is still an integer division. You need to cast one of the operands as a float, like e.g. float(gameWin) / gameNumber.
Also note that unless you're on a small embedded platform, or writing code to run on a GPU, then there's really no reason to use float these days. Using double is just as "fast" as using float, and double is also the default floating point type (for example when using floating point literals).

Homework: Cout incorrectly handling a return value of 0.0 from a class method

First, this is homework, so I can not dynamically allocate memory for an array of any size, and I can not use a vector.
I have a class which includes a double array holding 30 elements, and two other variables to keep track of how many elements have been added and the max number of elements that can be stored.
There are several methods that return the highest, lowest, average, and total from the elements in the array. An example of one of the methods is...
double Stats::sum() const
{
double sum = 0.0;
for (unsigned short i = 0; i < nElements; ++i)
sum += stats[i];
return sum;
};
In my main() function I have a cout statement...
cout << "\nTotal rainfall for " << MonthlyRainfall.size() << " months is "
<< MonthlyRainfall.sum() << " inches.\n";
When there are values in the array, the output is what I expect...
Total rainfall for 1 months is 1.5 inches.
However, when there are no values in the array (the method returns 0.0), but the output looks like...
Total rainfall for 0 months is -1.$ inches.
Can anyone help me understand what's happening in the cout statement that's causing the 0.0 returned by my method to output as it is?
Note: At the beginning of the main() function, the following statement is executed to format the decimal output. cout << fixed << showpoint << setprecision(1);
Update
I guess it was late and I was calling the average() method instead of sum(). I have fixed it and you also pointed out that I needed to make a couple changes to the average method to ensure a divide by 0 is not happening. (=
Divide-by-zero is well-defined to be positive or negative infinity. By default this displays as
Inf
or
-Inf
(at least on my machine).
setprecison messes this up, see this other question.
average() has divided something by zero and got minus infinity, and that's how cout has displayed it.
You failed to show the average method but my guess is that you do a divide by zero in there. Wackiness ensues.

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

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.