2014-03-04 51 views
-4

我無法找到我出錯的地方。計算器工作正常,但是當我想找到給定數字的階乘('!'用作操作符)時,我得到了奇怪的答案,如「1」和「59」。有人可以找到我滑倒並幫助的地方嗎?另外,對於我即將上傳的代碼長度感到抱歉。C++計算器程序 - 查找因子

#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; 
} 
+1

當您用手調用階乘函數時,如果出現正確的值,您是否嘗試過?如果在輸入階乘函數時調用了正確的值,您是否嘗試過? – Nobody

+1

你能刪除代碼中無關的部分嗎? **你已經試圖解決這個問題?**什麼有效,什麼沒有?你有什麼想法嗎?爲什麼?你的解決方案不起作用? –

+2

您應該花更多時間在格式上,以便所有代碼都能正確縮進,並且我還建議擺脫背靠背的空白行。 *可讀*代碼更有可能獲得積極的迴應。 – crashmstr

回答

1

int factorial (int x)算法很好。

但是,任何大於12!的東西都會溢出整數,如果它是32位有符號的。使用uint64_t會給你更多的數字(最多19!),但你應該提前檢查x的值。

0

更可能是因爲整數溢出而導致奇怪的結果。大於或等於13!的任何內容都將溢出32位int

0

您正在溢出32位int的最大大小。試試這個...

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

#incldue <limits> 

庫。任何int>什麼打印都會有不可知的結果。