Wrong result while trying to divide - c++

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).

Related

Having difficulties locating a problem in the for loop

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)).

conversion from double to float in c++

I am new to programming. Here is part of my assignment, which requires using pass-by-reference. After I compile it and type in the values for win, draw and loss respectively,it returns me nothing. I don't know whether it is due to the problem in calling the function or the floating point.
void Cfunction(int win, int draw, int loss, float& point)
{
point = win * 2.5f + draw * 1 + loss * 0;
}
int main(void)
{
int win, draw, loss;
float point;
cout << "Please input the game record in the following order: win draw loss " << endl;
cin >> win >> draw >> loss;
Cfunction(win, draw, loss, point);
cout << "The total score for the team is " << point << endl;
}
Look good to me.
You could verify that your cin >> ... has finished by adding a cout << "calculatin total score...." << std::endl;.
(Note: std::cin >> wins has the wins variable passed by reference, too :))
Indeed, as #David Hefferman suggested, learn to use the debugger. Will save you a huge amount of time in the (very near) future.
Looks fine to me too. You do know that you have to add the numbers one by one on their own lines, e.g. 5 , 3 , 4 ?

Dealing with a temperature program

I'm studying C++ by two months using the book : Programming principles and practice using C++. At the end of the error-handling chapter I have to write a program that convert degrees from Celsius to Fahrenheit and from Fahrenheit to Celsius, the program is really simple but my problem is with the error-handling.
This is my code (I use a special library written for the book's readers) :
#include "std_lib_facilities.h"
// convert from Celsius to Fahrenheit and from Fahrenheit to Celsius
int main()
try{
cout << "Please enter a double value representing a temperature : \n";
double val = 0;
cin >> val;
if (cin) {
double df = 9.0 / 5.0 * val + 32; // convert val to a Fahrenheit temperature
double dc = (val - 32) / 1.8; // convert val to a Celsius temperature
cout << "Celsius to Fahrenheit : " << df << '\n';
cout << "Fahrenheit to Celsius : " << dc << '\n';
}
else error("Couldn't read the value"); // if the last input operation fails
}
catch (runtime_error& e) {
cerr << "runtime error : " << e.what() << '\n';
return 1;
}
catch (...) {
cerr << "Oops, something went wrong somewhere\n";
return 2;
}
Here in my program I can just deal (in a very simple way) with an erroneous input value, but I can't deal with a possibile error caused by value too large to fit a double. I thought I could use numeric_limits, but I can just use features that the author has shown me. How would you solve this problem ? Would you allow the user to enter just "plausible" value for a temperature ? Or would you report an error if a value representing a temperature is too high or too low (like 1500 Celsius degrees) Thank you for your help ;)
Since the highest (and lowest) reasonable (and maybe even physically possible - http://en.wikipedia.org/wiki/Absolute_hot) temperatures are well within the bounds of a double, I would think that applying some more reasonable limit (which could be based on the physically possible temperatures or could be even narrower based on the specific application) would be the right approach.
Someone who enters a value outside that range has likely either made a mistake or is up to no good. The latter you want to stop, but the former you want to help by making sure whatever values you accept are "reasonable".
If you want limit numbers by double's capacity, then just check std::cin.good(). It returns true when everything is ok, and false when something is wrong (number too large to fit a double, inserted a letter instead of number, etc.).

C++ Money Class - storing and rounding cents

thanks in advance.
I'm writing a C++ assignment for class where we're creating our own money/currency class. I'm having trouble figuring out why my passing of a float isn't giving me enough precision.
Implementation:
private:
long int DOLLARS;
short int CENTS;
Currency::Currency(float tmpMoney)
{
// cout << "tmpMoney is: " << tmpMoney << endl;
int tmpDollar;
float tmpCent;
tmpDollar = static_cast<int>(tmpMoney);
tmpCent = (tmpMoney-tmpDollar)*100;
DOLLARS = tmpDollar;
CENTS = tmpCent;
}
Main Program:
Currency c1(2342.59);
Currency c2(2342.515); // there is no half cent coin, round it to 2342.52
If I output 'tmpMoney' it just gives me (for c2) 2345.51.
I'm not sure how to round .515 if the value doesn't even go that far.
It's a bad idea to make a currency type be constructible from floating-point type.
7 decimal digits is in general beyond float precision. You can still get desired output by:
float tmpMoney = 2342.515;
cout << setprecision(7) << tmpMoney << endl;
// 2342.515
But the internal representation is far from perfect:
cout << setprecision(10) << tmpMoney << endl;
// 2342.514893
If the number is large enough, you'll lose more:
float tmpMoney = 123456789.12;
cout << setprecision(12) << tmpMoney << endl;
// 123456792
So you may decide to use double instead, but you should be really careful because for large enough numbers you'll get the same errors:
double tmpMoney = 3333333333333333.42; // 17 digits
cout << setprecision(18) << tmpMoney << endl;
// 3333333333333333.5
If there is a chance that you'll have such numbers, don't initialize Currency with double either.
I would advise you to have just a constructor like Currency(int dollars, int cents).
You can also check this question for some insights.
#include <cmath>
CENTS = round(tmpCent);
Due to floating point representation, this may not always give the right result. The closest you can get is have a margin of error epsilon, say
#define EPS 0.000001
then you can do
CENTS = round(tmpCent + EPS);
Note that this will accept values that are represented as 0.499999 <= x < 0.5
And it's preferable to use double and not float to keep the precision as close as possible.

double multiplication is getting rounded, and i don't know how to fix it

My code is rounding my double values off, I'm multiplying two doubles, and it's roudning it off to an integer value. can someone help?
cout << "This program will determine the water needs for "
"a refugee camp based on the number of refugees, "
"daily water needs, and the existing water supplies."
<< endl
<< "Please enter the number of refugees: " << endl;
double NumOfRefugees = 0;
cin >> NumOfRefugees;
cout << "Please enter the daily water needs for each person "
"(in the range 7.5 to 15.0 liters per day.): " << endl;
double DailyNeedsPerPerson = 0;
cin >> DailyNeedsPerPerson;
if (DailyNeedsPerPerson < 7.5 || DailyNeedsPerPerson > 15.0)
{
cout << "The entered value is not within a reasonable range as specified in "
"the Sphere Project Humanitarian Charter. The program will now end.";
return 1;
}
double TotalDailyDemand = NumOfRefugees * DailyNeedsPerPerson;
cout << "The total demand is " << TotalDailyDemand << endl;
For example, when I input 15934 and 9.25, My code outputs:
This program will determine the water needs for a refugee camp based on the number of refugees, daily water needs, and the existing water supplies.
Please enter the number of refugees:
15934
Please enter the daily water needs for each person (in the range 7.5 to 15.0 liters per day.):
9.25
147390
The total demand is 147390
Please help!
What you are seeing is a result of the default precision of the output stream being 6 digits.
So, you need to apply some formatting to the output stream to be able to see more than the default 6 digits. For instance:
#include <iostream>
int main()
{
double x = 15934.0;
double y = 9.25;
double z = x*y;
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
std::cout.precision(2);
std::cout << z;
}
Output
147389.50
The call to setf is used to specify fixed floating point formatting with a specified number of digits after the decimal point. The call to precision specifies how many digits after the decimal point.
I'm not sure what formatting you actually want because you did not say. But these functions, and the relatives, should allow you to get the result that you desire.