1
votes

I am creating a calculator in Java, and am struggling to come up with a way to handle negative numbers, so far i can parse an expression, for example this:

((4-3)*(4/2))*2

becomes:

[4.0, -3.0, +, 4.0, 2.0, /, *, 2.0, *]

However i don't know how i would deal with expressions containing negatives, such as:

2*(-2-3)

So far i have it so when a negative value is encountered it multiplies the number ahead of it by -1 and adds a + to the end of the list, so the expression becomes this:

[2.0, -2.0, -3.0, +, +, *]

This is causing many errors in my program, can anyone help with a better method to deal with negatives.

Thanks very much for any help

3
You could maybe handle it by adding a 0 before any negative. Thus, 2*(-2-3) would become 2*(0-2-3).sp00m
Thanks for the quick reply, i have tried this, but when i have an expression like 8*-2 then i get the list [8.0, 0.0, *, -2.0, +] which causes an answer of -2user3120023
then you are parsing it wrong, 8*-2 should be [8, 0, 2, -, *], you read 8 => [8], you read * then you call to parse the next arg, you read - and 2 => [8, 0, 2, -], now you complete the * => [8, 0, 2, -, *]Vladp
maybe you should post how are you parsing, the problem might be there.Vladp

3 Answers

2
votes

Vladp is correct but to add some clarification.

You are implementing the Shunting Yard algorithm to turn infix notation into postfix notation, AKA Reverse Polish notation.

The problem you are having is that you are not distinguishing between a binary subtraction and a unary negate for the - character/symbol/operator.

So for

2*(-2-3)

You would convert this to an AST as

       *
      / \
  - (b)  2
    / \
- (u)  3
  /
 2

with - (b) being binary subtraction and - (u) being unary negation.

or RPN as

2-3-2*  

And evaluating as

2 - 3 - 2 *
(-2) 3 - 2 *
(-5) 2 *
-10 

When you evaluate a unary negate, just take the unary operator and next number off the stack and push a negative of that number on the stack. Unary negate does not mean multiple by negative one, but convert the operand to a negative.

So -5 negated is -5
and 5 negated is -5.

When you store the values for the negative sign, you must use two different operators, one for binary and one for unary. Also when you evaluate the operators, you must have a separate case for the unary and binary operators.

1
votes

Make two different - types,

one that works on a single value, by just turning it negative:

-(2+3)
[2, 3, +, type1-]

and second which works like +:

2-3
[2, 3, type2-]

together you should get:

2--3
[2, 3, type1-, type2-]

-2-(-3)
[2, type1-, 3, type1-, type2-]

When you encounter - with no arguments awaiting calculation it's type1 and type2 otherwise.

0
votes

Well, here's my two cents worth:

I suspect breaking up an equation that contains parentheses, within parentheses, etc into an array as you have done is going to lead to a lot of difficulties. I suggest you instead programmatically drill down into the deepest parentisis(s), process the data, and work outward. There might be on-line examples in Google on how to do this.