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.).
Related
I am new to Stack Overflow, and programming in general. I am in a few classes for programming C++ and have come across an assignment I am having a bit of trouble with. This program is supposed to take fahrenheit and convert it to celsius. I have seen other programs, but could not find a duplicate to my particular problem. This is my code.
#include <iostream>
using namespace std;
int main()
{
int fahrenheit;
cout << "Please enter Fahrenheit degrees: ";
cin >> fahrenheit;
int celsius = 5.0 / 9 * (fahrenheit - 32.0);
cout << "Celsius: " << celsius << endl;
return 0;
}
So this is working great on 4 of the 5 tests that are run. It rounds 22.22 to 22 and 4.44 to 4 like it should, but when 0 F is put in, it rounds -17.77 to -17 instead of -18. I have been researching for about an hour and would love some help! Thank you.
Use std::round() instead of relying on the implicit conversion from double to int. Either that, or do not use conversion at all, show the temperature as a double.
EDIT: As others already pointed out, implicit conversion will not round but truncate the number instead (simply cut off everything after the decimal point).
Integers round down implicitly, as do casts to integer types.
Most likely, using a float in place of an int would give the most sane results:
#include <iostream>
using namespace std;
int main()
{
int fahrenheit;
cout << "Please enter Fahrenheit degrees: ";
cin >> fahrenheit;
float celsius = 5.0 / 9 * (fahrenheit - 32.0);
cout << "Celsius: " << celsius << endl;
return 0;
}
To get normal-looking output (fixed-point like "14.25", not scientific with e notation), pass std::fixed to cout before printing the floating point. You can also use cout.precision() to set the number of digits you would like in the output.
If for some other reason you need an int, use std::round() around the right hand of the expression.
When the compiler converts a floating point number to an integer, it doesn't round, it truncates. I.e. it simply cuts of the digits after the decimal point. So your program behaves as it is programmed to do.
int x = 3.99;
int y = std::round(3.99);
std::cout
<< "x = " << x << std::endl
<< "y = " << y << std::endl
;
-->
x = 3
y = 4
C/C++ is not doing floating point round when static_cast<int>-ing a float to an int. If you want to round, you need to call library function std::round()
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).
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.
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.
I looked for a while and couldn't find an answer on here, but it seems to be a kind of weird question. I'm working with the fstream library in C++. What I'm trying to do is take data from an input file, assign it variables, and output this to both the screen and the output file. This is all for a project i'm working on that calculates the monthly payment of the car loan, which is why the variables are named the way they are.
My data file looks like this:
105670.00 12345.00 0.057 4
and essentially what is happening is I am losing everything after the decimal of the first two numbers (regardless of what i put as the decimal), but it doesn't happen to the 3rd number. additionally, when i try to setprecision(2) of the first two numbers i get a strange logic error, which i will show after my code.
my code looks like this:
#include<fstream>
#include<iomanip>
#include<iostream>
using namespace std;
int main ()
{
ifstream din; // These are my input and output files
ofstream dout;
float purchasePrice; // The first number of the input file.
float downPayment; // Second number.
float annualInterest; // Third number.
float numYears; // Last number.
// declaring the input/output files code here
din >> purchasePrice >> downPayment >> annualInterest >> numYears;
cout << purchasePrice << endl;
cout << downPayment << endl;
cout << annualInterest << endl;
cout << setprecision(2) << purchasePrice << endl;
cout << setprecision(2) << downPayment << endl;
cout << setprecison(2) << annualInterest << endl;
}
and here is my output:
105670
12345
0.057
1.1e+005
1.2e+004
0.057
I want my output to be:
105670.00
12345.00
0.057
105670.00
12345.00
0.05
Additionally, when performing any calculations, the numbers act as if they still have everything after the decimal. My question is, why are only some of the floats truncating, and why does setprecision() not work the way it is expected in this case?
Any responses are greatly appreciated, I'm sorry its such a lengthy explanation.
You also need to set the fmtflags to fixed:
std::cout << std::fixed << std::setprecision(2) << purchasePrice << "\n";
Without specifying scientific or fixed, the output mechanisms will use whatever scheme is deemed to be best. You know what's "best", and that's a fixed point scheme. For more detail, see http://en.cppreference.com/w/cpp/io/manip .
Even better is not to use floating point numbers at all when dealing with money. It is far better to use some fixed point arithmetic package.
float generally has 24 binary bits of precision which means that it can store about 6 decimal digits of precision so if your number is greater than 100000 you're not going to get any precision at all for decimal digits.
You should use double which has about 15 decimal digits of precision in this case instead of float
That answers your specific question most likely but if this is for money you probably shouldn't be using a floating format at all, as they can;t exactly represent 0.01 as a value for example, so all your calculations will be approximate and you probably don't want that when dealing with money. Generally hold the number of pence/cents/whatever in an integer and be careful :) Or even better a class specially designed for handling money values as there are often legal requirements on rounding etc.