Let me explain little further. I am writing a code to calculate the amount of water in swimming pool after filling it for some time at the filling rate.
Input taken is length
, width
, depth
in foot, time to fill the pool as timeToFillPool
in seconds, water filling rate in pool as fillingRate
in in US Gallons/minute, amount of water already in the pool as poolCurrWaterAmount
in US Gallons.
From this information I calculated total pool water capacity, totalPoolCapacity
, by multiplying length, width and depth and converting it to US Gallons.
I asked the user that how much water is already in the pool and then calculated and shown user appropriate messages like water can be filled or not if the pool is already full or water filled in given time will exceed pool capacity?
I am assuming all values input are positive or equal to zero if allowed to be zero.
#include <iostream>
#include <iomanip>
#include <cmath> //for fabs() functions
using namespace std ;
int main()
{
double timeToFillPool ;
double length, width, depth, fillingRate ;
double poolCurrWaterAmount, totalPoolCapacity ;
const double CUBIC_FOOT_TO_USGALLON = 7.48052 ; //i.e. 1 cubic foot = 7.48052 US Gallon
//setting tolerance value for comparing floating point numbers to 1/10000
//any thing less will be considered zero
const double EPSILON = 0.0001 ;
//preparing the output stream to print floating numbers in decimal
//form with precision to print two digits after decimal point
cout << fixed << setprecision(2);
cout << "Please enter swimming pool's dimensions,capacity,fill rate & drain rate information.\n";
cout << "Enter Length in foot : " ;
cin >> length ;
cout << "Enter width in foot : " ;
cin >> width ;
cout << "Enter depth in foot : " ;
cin >> depth ;
cout << "Enter filling rate of water in US Gallon/min : " ;
cin >> fillingRate ;
//calculating totalPoolCapacity in US Gallon
totalPoolCapacity = length * width * depth * CUBIC_FOOT_TO_USGALLON ;
cout << "\n\nTotal pool capacity = " << totalPoolCapacity << " US Gallon." ;
cout << "\n\nPlease enter current amount of water in pool in US Gallon to " ;
cout << "\nfill the pool according to filling rate for the specific amount of time in minutes : " ;
cin >> poolCurrWaterAmount ;
//to check minimum and maximum range of current amount of water.
while( !(poolCurrWaterAmount >= 0.0 && poolCurrWaterAmount <= totalPoolCapacity ) )
{
cout << "\nYou have entered in-valid value for current amount of water!"
<< "\nEnter current amount of water value from 0 to maximum capacity of pool "
<< setw(10) << totalPoolCapacity << " in US Gallon : " ;
cin >> poolCurrWaterAmount ;
}
cout << "\nPlease enter time in minute to fill water in pool : " ;
cin >> timeToFillPool ;
//Calculations and message displayed are on the basis of whether the filling water
//will cause overflow of water after filling the pool or not.
//managing floating point eqaulity poolCurrWaterAmount == totalPoolCapacity
//setting the tolerance value EPSILON to 1/10000 = 0.0001 of a US Gallon
if ( fabs(poolCurrWaterAmount - totalPoolCapacity) < EPSILON)
{
cout << "\n\nPool is Full. Water cannot be added." ;
cout << "\nTotal water in pool is " << setw(10) << totalPoolCapacity << " US Gallon." ;
}
else if (fillingRate * timeToFillPool > (totalPoolCapacity - poolCurrWaterAmount) )
{
//case to check that time entered for filling water will cause overflow of water or not
cout << "\n\nWarning! Pool will be overflowed with water! No water added!" ;
cout << "\nCurrent amount of water in pool = "
<< setw(10) << poolCurrWaterAmount << " US Gallon." ;
cout << "\nMaximum time required to completely fill the pool at\nfilling rate of "
<< setw(10) << fillingRate << " US Gallon/min is "
<< setw(10) << ( (totalPoolCapacity - poolCurrWaterAmount) / fillingRate ) << " minute." ;
}
else //case where time entered for filling water will not cause overflow of water in pool
{
cout << "\n\nCurrent amount of water in pool = "
<< setw(10) << poolCurrWaterAmount << " US Gallon." ;
cout << "\nAfter filling "
<< setw(10) << (fillingRate * timeToFillPool) << " US Gallon at filling rate of "
<< setw(10) << fillingRate << " US Gallons/min for "
<< setw(10) << timeToFillPool << " minute\nthe new amount of water in pool is "
<< setw(10) << ( poolCurrWaterAmount + fillingRate * timeToFillPool ) << " US Gallon." ;
}
}
//end of main function
this is the ouput of the program: -
***********************************
Please enter swimming pool's dimensions,capacity,fill rate & drain rate information.
Enter Length in foot : 3
Enter width in foot : 2
Enter depth in foot : 2
Enter filling rate of water in US Gallon/min : 4
Total pool capacity = 89.77 US Gallon.
Please enter current amount of water in pool in US Gallon to
fill the pool according to filling rate for the specific amount of time in minutes : 89.77
You have entered in-valid value for current amount of water!
Enter current amount of water value from 0 to maximum capacity of pool 89.77 in US Gallon :
************************************************************************************************
The problem is that the internal value stored in totalPoolCapacity
is 89.76624
and due to setprecision(2)
it rounds of the value to 89.77 so when I enter 89.77 it doesn't
accept it as a right value although it should be right value according to display message.
I don't want to show whole value to user.
Also please explain how to handle this calculation with setprecision(2)
(totalPoolCapacity - poolCurrWaterAmount) / fillingRate
and what will be good EPSILON
value to compare floating point numbers.
therefore time calculated and shown to user will not effect the overall calculation with rounding effects. That is what user sees, the program behaves according to that by manipulating internal representation of floating point numbers and their rounding off effects.
You should never do a floating point comparison like
poolCurrWaterAmount <= totalPoolCapacity
.Instead you should do
(poolCurrWaterAmount - totalPoolCapacity) < epsilon
.In your case, epsilon should be 0.005.
In general, for an equality operator, epsilon could be as small as DBL_EPSILON.
For a deep-dive into this topic, including more rigorous algorithms, see comparing-floating-point-numbers-2012-edition.