c ++计算器程序 - 查找因子

时间:2014-03-04 14:13:07

标签: c++ calculator factorial

我无法找到出错的地方。计算器工作正常,但当我想找到一个给定数字的阶乘('!'用作运算符)时,我得到奇怪的答案,如" 1"和" 59"。有人能找到我滑倒的地方吗?此外,抱歉我要上传的代码长度。

#include "Header.h"

class Token {
public:
char kind;        // what kind of token
double value;     // for numbers: a value 
Token(char ch)    // make a Token from a char
    :kind(ch), value(0) { }    
Token(char ch, double val)     // make a Token from a char and a double
    :kind(ch), value(val) { }
};


class Token_stream {
public: 
Token_stream();   // make a Token_stream that reads from cin
Token get();      // get a Token (get() is defined elsewhere)
void putback(Token t);    // put a Token back
private:      
bool full;  
Token buffer;     // here is where we keep a Token put back using putback()
};


// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
:full(false), buffer(0)    // no Token in buffer
{
}


// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
if (full) error("putback() into a full buffer");
buffer = t;       // copy t to buffer
full = true;      // buffer is now full
}


Token Token_stream::get()
{
if (full) {       // do we already have a Token ready?
    // remove token from buffer
    full=false;
    return buffer;
} 

char ch;
cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

switch (ch) {
case ';':    // for "print"
case 'q':    // for "quit"
case '(': case ')': case '+': case '-': case '*': case '/': case '{': case '}': case         '!':
    return Token(ch);        // let each character represent itself
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
    {    
        cin.putback(ch);         // put digit back into the input stream
        double val;
        cin >> val;              // read a floating-point number
        return Token('8',val);   // let '8' represent "a number"
    }
default:
    error("Bad token");
}
}


Token_stream ts;        // provides get() and putback() 



double expression();  // declaration so that primary() can call expression()


int factorial (int x)
{
int left = 1;
    for (int a = 1; a<=x;++a){
        left =a*left;
    }
        return left;
}

// deal with numbers and parentheses
double primary()
{
Token t = ts.get();
switch (t.kind) {
case '(':    // handle '(' expression ')'
    {    
        double d = expression();
        t = ts.get();
        if (t.kind != ')') error("')' expected)");
        return d;
    }
case '{':
    {
        double d = expression();
        t = ts.get();
        if (t.kind != '}') error ("'}' expected)");
        return d;
    }

case '8':
    return t.value;
default:
    return t.kind;
    error("primary expected");
}
}


// deal with *, /, and %
double term()
{
double left = primary();
Token t = ts.get();        // get the next token from token stream

while(true) {
    switch (t.kind) {
    case '*':
        left *= primary();
        t = ts.get();
        break;
    case '/':
        {    
            double d = primary();
            if (d == 0) error("divide by zero");
            left /= d; 
            t = ts.get();
            break;
        }
    case '!': 
        {
    Token t = ts.get();
    int d = factorial(t.value);
    return d;
        }

    default: 
        ts.putback(t);     // put t back into the token stream
        return left;
}
}
}


// deal with + and -
double expression()
{
double left = term();      // read and evaluate a Term
Token t = ts.get();        // get the next token from token stream

while(true) {    
    switch(t.kind) {
    case '+':
        left += term();    // evaluate Term and add
        t = ts.get();
        break;
    case '-':
        left -= term();    // evaluate Term and subtract
        t = ts.get();
        break;
    default: 
        ts.putback(t);     // put t back into the token stream
        return left;       // finally: no more + or -: return the answer
    }
}
}




int main()
try
{
while (cin) {
    double val = expression();
    Token t = ts.get();

    switch(t.kind){
case 'q': cout<<"end of programme";
    break;
case ';':        // ';' for "print now"
        cout << "=" << val << '\n';
        break;
default:
        ts.putback(t);
    val = expression();
    }
}
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n'; 
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n"; 
keep_window_open();
return 2;
}

3 个答案:

答案 0 :(得分:1)

int factorial (int x)在算法上很好。

,如果是32位签名,任何大于12!的内容都会溢出整数。使用uint64_t会为您提供更多数字(最多19!),但您应该提前检查x的值。

答案 1 :(得分:0)

很可能,由于整数溢出,您会得到奇怪的结果。任何大于或等于13!的内容都会溢出32位int

答案 2 :(得分:0)

你正在溢出32位int的最大大小。试试这个......

 std::cout << std::numeric_limits<int>::max(); 

使用

#incldue <limits>

库。任何int&gt;什么印刷品会有不可知的结果。