Android Open Source - Calculator-for-Android Big Decimal Postfix Evaluator






From Project

Back to project page Calculator-for-Android.

License

The source code is released under:

Apache License

If you think the Android project Calculator-for-Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

//   Copyright 2012 Digipom Inc.
////ww  w .j  av  a2 s .  co m
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.digipom.android.library.evaluator;

import java.math.BigDecimal;

import com.digipom.android.library.evaluator.exception.ParseException;

/**
 * This evaluator is far slower than the float or double evaluators.
 */
public class BigDecimalPostfixEvaluator extends PostfixEvaluator {
  private final BigDecimal[] operandStack = new BigDecimal[4096];
  private int stackPointer = -1;

  public BigDecimalPostfixEvaluator(String input) throws ParseException {
    super(input, NumberPrecision.BIG_DECIMAL);
  }    

  public BigDecimal evaluate() throws ParseException {
    for (final FlatToken token : postfixExpression) {
      switch (token.type) {
        case FlatToken.TYPE_IDENTIFIER:
        case FlatToken.TYPE_NUMBER_LITERAL:
          operandStack[++stackPointer] = token.bigDecimalValue;
          break;
        case FlatToken.TYPE_OPERATOR:
          if (token.typeEnum == FlatToken.OPERATOR_NEGATE) {
            final BigDecimal a = operandStack[stackPointer--];
            operandStack[++stackPointer] = a.negate();
          } else {
            final BigDecimal b = operandStack[stackPointer--];
            final BigDecimal a = operandStack[stackPointer--];

            switch (token.typeEnum) {
              case FlatToken.OPERATOR_ADD:
                operandStack[++stackPointer] = a.add(b);
                break;
              case FlatToken.OPERATOR_SUBTRACT:
                operandStack[++stackPointer] = a.subtract(b);
                break;
              case FlatToken.OPERATOR_MULTIPLY:
                operandStack[++stackPointer] = a.multiply(b);
                break;
              case FlatToken.OPERATOR_DIVIDE:
                stackPointer++;
                try {
                  operandStack[stackPointer] = a.divide(b);
                } catch (ArithmeticException e) {
                  // Try using double values
                  // TODO: No, should use precision instead.
                  operandStack[stackPointer] = new BigDecimal(a.doubleValue() / b.doubleValue());
                }
                
                break;
              case FlatToken.OPERATOR_POWER:
                operandStack[++stackPointer] = new BigDecimal(
                    Math.pow(a.doubleValue(), b.doubleValue()));
                break;
            }
          }
          break;
        case FlatToken.TYPE_PREDEF_FUNCTION:
          if (token.typeEnum == FlatToken.FUNCTION_POW) {
            final BigDecimal b = operandStack[stackPointer--];
            final BigDecimal a = operandStack[stackPointer--];
            operandStack[++stackPointer] = new BigDecimal(Math.pow(a.doubleValue(), b.doubleValue()));
          } else {
            final BigDecimal a = operandStack[stackPointer--];

            switch (token.typeEnum) {
              case FlatToken.FUNCTION_ABS:
                operandStack[++stackPointer] = a.abs();
                break;
              case FlatToken.FUNCTION_SIN:
                operandStack[++stackPointer] = new BigDecimal(Math.sin(a.doubleValue()));
                break;
              case FlatToken.FUNCTION_COS:
                operandStack[++stackPointer] = new BigDecimal(Math.cos(a.doubleValue()));
                break;
              case FlatToken.FUNCTION_TAN:
                operandStack[++stackPointer] = new BigDecimal(Math.tan(a.doubleValue()));
                break;
              case FlatToken.FUNCTION_LN:
                operandStack[++stackPointer] = new BigDecimal(Math.log(a.doubleValue()));
                break;
              case FlatToken.FUNCTION_SQRT:
                operandStack[++stackPointer] = new BigDecimal(Math.sqrt(a.doubleValue()));
                break;
            }
          }
          break;
      }
    }

    if (stackPointer != 0) {
      stackPointer = -1;
      throw new ParseException("Error evaluating expression");
    }

    return operandStack[stackPointer--];
  }
}




Java Source Code List

com.digipom.android.library.evaluator.BigDecimalPostfixEvaluator.java
com.digipom.android.library.evaluator.DoublePostfixEvaluator.java
com.digipom.android.library.evaluator.FloatPostfixEvaluator.java
com.digipom.android.library.evaluator.NumberPrecision.java
com.digipom.android.library.evaluator.PostfixEvaluator.java
com.digipom.android.library.evaluator.ShuntingYardParser.java
com.digipom.android.library.evaluator.TestBigDecimalEvaluator.java
com.digipom.android.library.evaluator.TestDoubleEvaluator.java
com.digipom.android.library.evaluator.TestFloatEvaluator.java
com.digipom.android.library.evaluator.TestShuntingYardParser.java
com.digipom.android.library.evaluator.builder.ExpressionBuilder.java
com.digipom.android.library.evaluator.builder.StringNumberLiteral.java
com.digipom.android.library.evaluator.exception.ParseException.java
com.digipom.android.library.evaluator.lexer.BigDecimalNumberLiteral.java
com.digipom.android.library.evaluator.lexer.DoubleNumberLiteral.java
com.digipom.android.library.evaluator.lexer.FloatNumberLiteral.java
com.digipom.android.library.evaluator.lexer.Identifier.java
com.digipom.android.library.evaluator.lexer.Lexer.java
com.digipom.android.library.evaluator.lexer.NumberLiteral.java
com.digipom.android.library.evaluator.lexer.Operator.java
com.digipom.android.library.evaluator.lexer.Parenthesis.java
com.digipom.android.library.evaluator.lexer.PredefinedFunction.java
com.digipom.android.library.evaluator.lexer.Separator.java
com.digipom.android.library.evaluator.lexer.TestLexer.java
com.digipom.android.library.evaluator.lexer.Token.java
com.digipom.android.library.util.ObjectUtils.java
com.digipom.android.library.util.TestObjectUtils.java
com.digipom.calculator.config.LoggerConfig.java
com.digipom.calculator.logic.Calculator.java
com.digipom.calculator.logic.Memory.java
com.digipom.calculator.ui.CalculatorActivity.java