Reputation: 307
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
Upvotes: 1
Views: 5239
Reputation: 24976
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.
Upvotes: 2
Reputation: 287
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.
Upvotes: 0
Reputation: 4402
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.
Upvotes: 1