I am making a console based calculator application. The application processes user keypresses to perform its operations. Integral inputs work fine; however, I am facing problems writing the code for the case where the user presses a backspace to erase a decimal number.
The code that I wrote to erase decimal spaces is as follows:
decimalcount--; // number of decimal places is subtracted by 1
lnum -= fmod (lnum, pow (10, -decimalcount + 1)); // subtraction
cout << setprecision (decimalcount) << lnum << endl; // display the code
However, for certain numbers like 12.00400679, the values are being improperly subtracted:
12.00400679
12.00400670
12.0040060
12.004000
12.00400
12.0040
12.000
11.90
11.0
10
The full source of the program is as below:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <conio.h>
using namespace std;
int sgn (double x)
{
if (x < 0)
{
return -1;
}
return 1;
}
int main ()
{
cout.setf (ios::fixed);
double lnum = 0, expr = 0;
int decimalcount = 0;
char ch, op;
while (true)
{
ch = _getch ();
if (isdigit (ch))
{
if (! decimalcount)
{
if (sgn (lnum) == sgn (lnum * 10 + sgn (lnum) * (ch - 48)))
{
lnum = lnum * 10 + sgn(lnum) * (ch - 48);
cout << setprecision (0) << lnum << endl;
}
}
else
{
if (decimalcount < 9)
{
lnum += sgn (lnum) * (ch - 48) * pow (10, -decimalcount);
cout << setprecision (decimalcount) << lnum << endl;
decimalcount++;
}
}
}
else if (ch == '\b')
{
if (! decimalcount)
{
lnum -= fmod (lnum, 10);
lnum /= 10;
cout << setprecision (0) << lnum << endl;
}
// This is where I am having problems
else
{
decimalcount--;
lnum -= fmod (lnum, pow (10, -decimalcount + 1));
cout << setprecision (decimalcount) << lnum << endl;
}
}
else if (ch == '.')
{
if (! decimalcount)
{
decimalcount = 1;
cout << setprecision (decimalcount) << lnum << endl;
}
}
else if (ch == 'x')
{
return 0;
}
}
}
Can anyone show me where I am doing it wrong?
Thanks in advance,
You’re converting too early. During input, you should keep the
input as a string, and only convert to your internal format when
the input is finished, and you’re ready to do the calculations.
But you seem to be doing things the hard way. Why not just use
std::getlineonstd::cin, and parse the text you receive?That way, the system handles things like back space, and you
don’t have to. If for some reason this isn’t acceptable, you
should still factor the input out into a separate function,
which does more or less the same thing.