-1

I am writing a Prefix Calculator program and because of the way prefix is structured, it is difficult to deal with dividing by zero. Fortunately, C++ has a built in exception if it divides by zero. How would I handle the following exception so that it returns a personalized message to the console rather than popping this window up? I NEED THIS WINDOW TO NOT POP UP WHEN I DIVIDE BY ZERO.

enter image description here

template<class T>
T PrefixCalculator<T>::eval(istringstream& input) {  //this function needs to throw an     exception if there's a problem with the expression or operators
char nextChar = input.peek();

//handles when invalid characters are input
if(nextChar > '9' || nextChar == '.' || nextChar == ',' || nextChar < '*' &&      nextChar != 'ÿ') {
    throw "invalidChar";
}

//this while loop skips over the spaces in the expression, if there are any
while(nextChar == ' ') {
    input.get();    //move past this space
    nextChar = input.peek(); //check the next character
}

if(nextChar == '+') {
    input.get();    //moves past the +
    return eval(input) + eval(input);   //recursively calculates the first expression, and adds it to the second expression, returning the result
}

/***** more operators here ******/
if(nextChar == '-') {
    input.get();
    return eval(input) - eval(input);
}

if(nextChar == '*') {
    input.get();
    return eval(input) * eval(input);
}

if(nextChar == '/') {
    input.get();

    return eval(input) / eval(input);
}

/******  BASE CASE HERE *******/
//it's not an operator, and it's not a space, so you must be reading an actual  value (like '3' in "+ 3 6".  Use the >> operator of istringstream to pull in a T value!
input>>nextChar;
T digit = nextChar - '0';

return digit;
//OR...there's bad input, in which case the reading would fail and you should throw an exception
}

template<class T>
void PrefixCalculator<T>::checkException() {
if(numOperator >= numOperand && numOperator != 0 && numOperand != 0) {
    throw "operatorError";
}
if(numOperand > numOperator + 1) {
    throw "operandError";
}
}
jordpw
  • 181
  • 2
  • 16
  • 4
    That's not a C++ exception IIRC, but a "Hardware Exception" that can be treated via [SEH](http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657%28v=vs.85%29.aspx). See http://stackoverflow.com/q/1909967/420683 and http://stackoverflow.com/questions/4747934/c-catch-a-divide-by-zero-error – dyp May 02 '14 at 00:30
  • What did you try in code? `try{} catch(...){}`(no pun intended ;)!) – πάντα ῥεῖ May 02 '14 at 00:30

1 Answers1

3

The notation you're using to interpret complex operations, doesn't change the way you're doing your low-level operations - like division. Somewhere in your code you have to perform a simple x/y and in that place, when you know you're gonna divide, check for 0:

if(y==0)
   // your error handling goes here, maybe simple y=1
stack.pushBack(x/y);

Note that in C++ a division by 0 isn't really an exception. Quoting Stroustrup - the creator of the language:

"low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."

In your case:

if(nextChar == '/') {
    input.get();
    T x = eval(input);
    T y = eval(input);

    if(!y) handlingTheVeryDifficultSituation();
    return x/y;
}
Paweł Stawarz
  • 3,952
  • 2
  • 17
  • 26
  • There is no clear place in the code where the division by zero happens, because it is prefix notation. During runtime, the compiler will divide by zero, and then give that error box. As far as youre concerned, i have to handle that specific exception given, which is why my question isn't really a duplicate. – jordpw May 02 '14 at 00:35
  • 1
    @jordpw can you provide the code for computing the equation (already stored in the RPN)? The error checking should be implemented inside parsing. The notation really doesn't matter. – Paweł Stawarz May 02 '14 at 00:39
  • ... and then someone manages to put `INT_MIN` in `x` and `-1` in `y`, and [you get a DoS issue in win32k.sys](https://gist.github.com/taviso/4658638) (http://blog.regehr.org/archives/887) – Matteo Italia May 02 '14 at 00:43
  • i have added relevant code to the original question. How would i go about throwing the exception myself? – jordpw May 02 '14 at 02:08
  • 1
    @jordpw simply just under `if(nextChar == '/')`, assign both `eval(input)` to temporary variables and check for 0 then? I'll edit my post to show it, but its kinda straighforward... – Paweł Stawarz May 02 '14 at 02:20