我正在制作一个基于控制台的计算器应用程序。应用程序处理用户按键以执行其操作。积分输入工作正常;但是,我在编写用户按下退格键以删除十进制数字的情况时遇到问题。
我写的用于擦除小数空格的代码如下:
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
但是,对于某些数字(如12.00400679),值被不正确地减去:
12.00400679
12.00400670
12.0040060
12.004000
12.00400
12.0040
12.000
11.90
11.0
10
该计划的完整来源如下:
#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;
}
}
}
有人能告诉我我做错了吗?
提前致谢,
答案 0 :(得分:6)
你过早转换。在输入过程中,你应该保持 输入为字符串,并且只在转换为内部格式时 输入已完成,您已准备好进行计算。
但你似乎正在以艰难的方式做事。为什么不用
std::getline
std::cin
,并解析您收到的文字?
这样,系统处理后空间等事情
不必。如果由于某种原因这是不可接受的,你
仍应将输入分解为单独的函数,
这或多或少都是一样的。
答案 1 :(得分:2)
这是因为这些值不能用浮点数精确表示。值得一读的是如何在内存中表示浮点数。
如果您需要精确的小数位,最好使用定点算术。但是,实现trig函数等可能会很烦人,除非您为此类操作转换为浮点数。
答案 2 :(得分:0)
您应该避免对数字执行算术运算,因为这可能会改变您想要保留的有效数字。相反,您可以将其转换为字符串并截断它,然后在需要实际算术值时转换回来。例子:
double d;
// ...
std::ostringstream sstream;
sstream << d;
std::string str = sstream.str();
或者:
char str[10];
snprintf(str, 10, "%g", d);
但总的来说,我会选择James Kanze的答案,并将所有输入存储为字符串,最后只转换为数值。