2

我正在制作一个基于控制台的计算器应用程序。应用程序处理用户按键以执行其操作。积分输入工作正常;但是,我在为用户按下退格键擦除十进制数的情况下编写代码时遇到问题。

我为擦除小数位而编写的代码如下:

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;
        }
    }

}

谁能告诉我我做错了什么?

提前致谢,

4

3 回答 3

6

你转换得太早了。在输入过程中,您应该将输入保留为字符串,并且仅在输入完成后转换为您的内部格式,并且您已准备好进行计算。

但你似乎做事很艰难。为什么不直接使用 std::getlineonstd::cin并解析您收到的文本?这样,系统就可以处理诸如退格之类的事情,而您不必这样做。如果由于某种原因这是不可接受的,您仍然应该将输入分解为一个单独的函数,它或多或少地做同样的事情。

于 2013-02-12T09:38:20.340 回答
2

这是因为这些值不能用浮点数精确表示。值得一读关于浮点在内存中的表示方式。

如果您需要精确的小数位,最好使用定点算术。但是,除非您将此类操作转换为浮点数,否则实现三角函数等可能会很烦人。

于 2013-02-12T09:31:19.617 回答
0

您应该避免对数字执行算术运算,因为这可能会改变您想要保留的有效数字。相反,您可以将其转换为字符串并截断它,然后在需要实际算术值时再转换回来。例子:

double d;

// ...

std::ostringstream sstream;
sstream << d;
std::string str = sstream.str();

或者:

char str[10];
snprintf(str, 10, "%g", d);

但总的来说,我会选择 James Kanze 的答案并将所有输入存储为字符串,最后只转换为数值。

于 2013-02-12T09:41:26.463 回答