"Floating Point Exception"

So, I'm trying to finish a program that converts an infix expression to postfix then evaluates that postfix expression. I'm using an input file and when I getline the first line of the file, it'll convert it to postfix, but when I evaluate it, all I get is "floating point exception".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <fstream>
#include <stack>
#include <ctype.h>
#include <sstream>
using namespace std;

int prec(char elem)
  {
    switch(elem)
      {
        case '^' : return 3;
        case '*' : return 2;
        case '/' : return 2;
        case '+' : return 1;
        case '-' : return 1;
        case '(' : return 0;

        default  : return -1;
      }
  }

int eval(char opn1, char elem, char opn2)
  {
    int result;
    switch(elem)
      {
        case '+' : result = opn1 + opn2;
        case '-' : result = opn1 - opn2;
        case '*' : result = opn1 * opn2;
        case '/' : result = opn1 / opn2;
        case '^' : result = opn1 ^ opn2;
      }
    return result;
  }

void in_to_post(string st)
  {
    string post;
    char tok, opn1, opn2;
    int result;
    stack <char> ifx;
    stack <char> pfx;
    stringstream output, out2;

    for(int i = 0; i <= st.length(); i++)
      {
        if(st[i] == ' ') i++;
        if(st[i] == '^' || st[i] == '*' || st[i] == '/' ||
           st[i] == '+' || st[i] == '-')
          {
            while(!ifx.empty() && prec(st[i]) <= prec(ifx.top()))
              {
                output << ifx.top();
                ifx.pop();
              }
            ifx.push(st[i]);
          }
        else if(st[i] == '(')
          {
            ifx.push(st[i]);
          }
        else if(st[i] == ')')
          {
            while(ifx.top() != '(')
              {
                output << ifx.top();
                ifx.pop();
              }
            ifx.pop();
          }
        else
          {
            output << st[i];
          }
      }
    while(!ifx.empty())
      {
        output << ifx.top();
        ifx.pop();
      }

    cout << output.str() <<endl;
    post = output.str();

    for(int i = 0; i < post.length(); i++)
      {
        tok = post[i];
        if(isdigit(tok))
          {
            pfx.push(tok);
          }
        else
          {
            opn2 = pfx.top();
            pfx.pop();
            opn1 = pfx.top();
            result = eval(opn1, tok, opn2);
            pfx.push(result);
          }
      }
    while(!pfx.empty())
      {
        out2 << pfx.top();
        pfx.pop();
      }
    cout << out2.str() << endl;
  }

int main()
  {
    string st, post;
    ifstream infix;
    stringstream output;

    infix.open("x.data");
    while(getline(infix, st))
      {
        cout << st << endl;
        in_to_post(st);
      }
    infix.close();
    return 0;
  }


So, I know the problem is in the second for loop, but IDK how to fix it.

Input file: "x.data"

2 + 3 * 5
2 + 3 * 5 ^ 6
2 + 3 - 5 + 6 - 4 + 2 - 1
2 + 3 * ( 5 - 6 ) - 4
2 + 3 ^ 5 * 6 - 4
2 + 3 * 6 ^ 2
( ( ( ( 2 + 3 - 4 ) / 2 + 8 ) * 3 * ( 4 + 5 ) / 2 / 3 + 9 ) )
Take a look at the comments in the code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <iostream>
#include <fstream>
#include <stack>
#include <ctype.h>
#include <sstream>
//----------------------------
// Added for pow function
#include <cmath>
using namespace std;

int prec(char elem)
  {
    switch(elem)
      {
        case '^' : return 3;
        case '*' : return 2;
        case '/' : return 2;
        case '+' : return 1;
        case '-' : return 1;
        case '(' : return 0;

        default  : return -1;
      }
  }

int eval(char opn1, char elem, char opn2)
  {
    int result;
    switch(elem)
      {
        //--------------------------------------------------
        // Added the breaks
        case '+' : result = opn1 + opn2;break;
        case '-' : result = opn1 - opn2;break;
        case '*' : result = opn1 * opn2;break;
        case '/' : result = opn1 / opn2;break;
        //--------------------------------------------------
        // This has to be a the pow function because
        // ^ is XOR not to the power
        case '^' : result = int(pow(float(opn1),float(opn2)));break;
      }
    return result;
  }

void in_to_post(string st)
  {
    string post;
    char tok,opn1,opn2;
    int result;
    stack <char> ifx;
    stack <char> pfx;
    stringstream output, out2;

    //------------------------------------------------------
    // i should be just < not <= st.length()
    for(int i = 0; i < st.length(); i++)
      {
        if(st[i] == ' ') i++;
        if(st[i] == '^' || st[i] == '*' || st[i] == '/' ||
           st[i] == '+' || st[i] == '-')
          {
            while(!ifx.empty() && prec(st[i]) <= prec(ifx.top()))
              {
                output << ifx.top();
                ifx.pop();
              }
            ifx.push(st[i]);
          }
        else if(st[i] == '(')
          {
            ifx.push(st[i]);
          }
        else if(st[i] == ')')
          {
            while(ifx.top() != '(')
              {
                output << ifx.top();
                ifx.pop();
              }
            ifx.pop();
          }
        else
          {
            output << st[i];
          }
      }
    while(!ifx.empty())
      {
        output << ifx.top();
        ifx.pop();
      }

    cout << output.str() <<endl;
    post = output.str();

    for(int i = 0; i < post.length(); i++)
      {
        tok = post[i];
        if(isdigit(tok))
          {
            pfx.push(tok);
          }
        else
          {
            opn2 = pfx.top();
            pfx.pop();
            opn1 = pfx.top();
            //---------------------------------------------
            // Added the pop
            pfx.pop();

//-----------------------------------------------------
// Cheated here by substacting the 0x30, but this
// is where your real issues start.  This will work for 
// the first equation because the value of the result and
// all intermeditate results are less than 8 bits.  As soon
// as you try the second equation, the 5^6 (15,625) blows 
// that apart and the code is broken.  Once you start to 
// populate pfx, the values stored must be integers and 
// not chars.  In that case the 0x30s would come out of 
// the function call below and other spots below.  But then 
// where do you do that?  If all of the numbers in the 
// x.data file are never larger that one character than 
// down here maybe, if not than you would have to change 
// the loop above and the parsing becomes more complex.
// 
// Take a look and see if just making the changes have pfx
// a stack<int> is OK.

            result = eval(opn1-0x30, tok, opn2-0x30);
            pfx.push(result+0x30);
          }
      }
    while(!pfx.empty())
      {
        out2 << pfx.top()-0x30;
        pfx.pop();
      }
    cout << out2.str() << endl;
  }

int main()
  {
    string st, post;
    ifstream infix;
    stringstream output;

    infix.open("x.data");
    while(getline(infix, st))
      {
        cout << st << endl;
        in_to_post(st);
      }
    infix.close();
    return 0;
  }
$ ./a.out
2 + 3 * 5
235*+
17                      <------- Right
2 + 3 * 5 ^ 6
2356^*+
29                      <------- Wrong because of 5^6
2 + 3 - 5 + 6 - 4 + 2 - 1
23+5-6+4-2+1-
3                        <------- Right
2 + 3 * ( 5 - 6 ) - 4
2356-*+4-
-5                       <------- Right
2 + 3 ^ 5 * 6 - 4
235^6*+4-
-80                     <------- Wrong
2 + 3 * 6 ^ 2
2362^*+
-146                   <------- Wrong
( ( ( ( 2 + 3 - 4 ) / 2 + 8 ) * 3 * ( 4 + 5 ) / 2 / 3 + 9 ) )
23+4-2/8+3*45+*2/3/9+
3                       <------- Wrong because of fractions
$
Last edited on
Topic archived. No new replies allowed.