Android Open Source - bin.calc_android Calculator






From Project

Back to project page bin.calc_android.

License

The source code is released under:

GNU General Public License

If you think the Android project bin.calc_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

package info.ohgita.android.bincalc;
/*from ww w .java  2 s . c  o m*/
import info.ohgita.android.bincalc.calculator.BaseConverter;
import info.ohgita.android.bincalc.calculator.BasicArithOperator;
import info.ohgita.android.bincalc.calculator.ExpParser;
import info.ohgita.android.bincalc.calculator.HistoryItem;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;

import android.util.Log;
import android.widget.Toast;

/**
 * bin.Calc Internal calculator class
 * @author Masanori Ohgita
 */
public class Calculator {
  protected ExpParser expParser;  // Numerical-expression (Numerical formula) parser object
  protected BasicArithOperator basicArithOperator;  // Basic arithmetic operator object
  protected BaseConverter baseConverter;  // Base converter object
  
  protected String EXP_SYMBOLS[] = {"(",")","*","/","+","-"};
  
  protected CalculatorMemoryData memory;
  
  public ArrayList<HistoryItem> histories;
  
  /**
   * Constructor
   * @param arith_round_scale  Rounding scale for BasicArithOperator
   */
  public Calculator(int arith_round_scale){
    /* Initialize instances */
    expParser = new ExpParser();
    basicArithOperator = new BasicArithOperator(arith_round_scale);
    baseConverter = new BaseConverter();
    
    histories = new ArrayList<HistoryItem>();
    memory = null;
    
    /* Initialize sort for binarySearch */
    Arrays.sort(EXP_SYMBOLS);
    
  }
  
  /**
   * MemoryIn method
   */
  public void InMemory(int base_type, String value){
    memory = new CalculatorMemoryData();
    memory.base_type = base_type;
    memory.value = value;
  }
  
  /**
   * MemoryOut (Read) method
   */
  public CalculatorMemoryData readMemory(){
    if (memory != null)
      return memory;
    return null;
  }
  
  /**
   * MemoryClear method
   */
  public void clearMemory(){
    memory = null;
  }
  
  /**
   * Calculate a numerical formula
   * @param exp Numerical formula (Decimal numbers)
   * @return Calculated result
   */
  public String calc(String exp) throws Exception {
    Log.d("binCalc", "Calculator - calc("+exp+")");
    
    /* Parse a numerical formula */
    LinkedList<String> list = parseToList(exp);
    
    /* Calculate formula */
    String res = basicArithOperator.calculate(list);

    Log.d("binCalc", "Calculator - calc - Answer: "+res);
    return res;
  }
  
  /**
   * Parse a numerical formula, and convert to a LinkedList.
   * @param exp Numerical formula (Decimal numbers)
   * @return Parsed LinkedList
   */
  public LinkedList<String> parseToList(String exp){
    Log.d("binCalc", "parseToList("+exp+")");
    return expParser.parseToList(exp);
  }
  
  /**
   * Base number convert from LinkedList
   * @param list LinkedList (Parsed numerical formula)
   * @param fromNBase Source base
   * @param destNBase Destination base
   * @return Converted result
   * @throws Exception 
   */
  public CalculatorBaseConvResult listBaseConv(LinkedList<String> list, int fromNBase, int destNBase ) throws Exception{
    Log.d("binCalc", "Calculator.listBaseConv(list, "+fromNBase+", "+destNBase+")");
    baseConverter = new BaseConverter();
    Iterator<String> iter = list.iterator();
    StringBuilder resultExp = new StringBuilder();
    
    while(iter.hasNext()){
      String chunk = iter.next();
      
      String conv = null;
      if(Arrays.binarySearch(EXP_SYMBOLS, chunk) < 0){ // if number
        
        if(fromNBase == 10){
          /* Convert DEC(10) -> NADIC( 2 or 16 ) */
          conv = baseConverter.decToN(Double.parseDouble(chunk), destNBase);
          
        }else if(fromNBase == 2){
          
          if(destNBase == 10){
            /* Convert BIN(2) -> DEC(10) */
            Double d =baseConverter.binToDec(chunk);
            if(isDecimalFraction(2, chunk) == true){
              conv = d.toString();
            }else{
              conv = d.intValue() + ""; // Remove the decimal fraction point
            }
          }else if(destNBase == 16){
            /* Convert BIN(2) -> DEC(16) */
            conv = baseConverter.decToN( baseConverter.binToDec(chunk), 16);
          }
          
        }else if(fromNBase == 16){
          
          if(destNBase == 2){
            /* Convert HEX(16) -> BIN(2) */
            conv = baseConverter.decToN( baseConverter.hexToDec(chunk), 2);
          }else if(destNBase == 10){
            /* Convert HEX(16) -> DEC(10) */
            Double d = baseConverter.hexToDec(chunk);
            if(isDecimalFraction(16, chunk) == true){
              conv = d.toString();
            }else{
              conv = d.intValue() + ""; // Remove the decimal fraction point
            }
          }
        }
        
        /* Insert the separator into number */
        conv = insertSeparator(conv, destNBase);
        /* Insert space for a point */
        //conv = insertSpaceForPoint(conv);
        
      } else {
        conv = chunk;
      }
      
      resultExp.append(conv);
    }
    
    CalculatorBaseConvResult result = new CalculatorBaseConvResult(); 
    result.logs = baseConverter.getLogs();
    result.value = resultExp.toString();
    return result;
  }
  
  /**
   * Convert LinkedList to String (Numerical formula) 
   * @param list LinkedList (Parsed numerical formula)
   * @param nBase Source base
   * @return Numerical formula string
   * @throws Exception 
   */
  public String listToString(LinkedList<String> list, int nBase) throws Exception{
    Log.d("binCalc", "Calculator.listToString(list, "+nBase+")");
    Iterator<String> iter = list.iterator();
    StringBuilder resultExp = new StringBuilder();
    
    while(iter.hasNext()){
      String chunk = iter.next();
      Log.i("binCalc", chunk);
      if (Arrays.binarySearch(EXP_SYMBOLS, chunk) < 0){ // If number
        if (nBase == 10) { // Decimal
          if (chunk.contentEquals("-0") == false){ // Not minus zero
            /* Insert the separator to number */
            chunk = insertSeparator(chunk, nBase);
          }
        } else if (nBase == 2) { // Binary
          /* Insert the separator to number */
          chunk = insertSeparator(chunk, nBase);
          /* Insert space for a point */
          //chunk = insertSpaceForPoint(chunk);
        }
      }
      
      resultExp.append(chunk);
    }
    Log.d("binCalc", "  => "+resultExp.toString());
    return resultExp.toString();
  }
  
  /**
   * Remove parenthesis for LinkedList
   * @param list LinkedList (Parsed numerical formula)
   * @return Processed LinkedList
   */
  public LinkedList<String> listRemoveParentheses(LinkedList<String> list){
    Log.d("binCalc", "Calculator.removeParentheses(list)");
    LinkedList<String> ret_list = new LinkedList<String>(); 
    for(int i=0;i<list.size();i++){
      String chunk = list.get(i);
      if(chunk.contentEquals("(") == false && chunk.contentEquals(")") == false){
        // if NOT parenthesis...
        ret_list.add(chunk);
      }
    }
    return ret_list;
  }
  
  /**
   * Zero-padding for LinkedList
   * @param list LinkedList (Parsed numerical formula)
   * @param nBase Source base
   * @return Processed LinkedList
   */
  public LinkedList<String> listZeropadding(LinkedList<String> list, int nBase){
    Log.d("binCalc", "Calculator.listZeropadding(list, "+nBase+")");
    for(int i=0;i<list.size();i++){
      String chunk = list.get(i);
      if(Arrays.binarySearch(EXP_SYMBOLS, chunk) < 0){// if number
        if(nBase == 2){ // binary
          list.set(i, baseConverter.binZeroPadding(chunk));
        }
      }
    }
    return list;
  }
  
  /**
   * Find Last number-chunk from the list
   * @param list LinkedList (Parsed numerical formula)
   * @return Found chunk (Last number-chunk)
   */
  public int indexOfListLastNumberChunk(LinkedList<String> list) {
    if (list.isEmpty() == false) {
      // Find last number-chunk
      for (int i = list.size() - 1; 0 <= i; i--) {
        String chunk = list.get(i);
        if (0 < chunk.length() && chunk.contentEquals("(") == false
            && chunk.contentEquals(")") == false) {
          return i;
        }
      }
    }
    return -1;
  }
  
  /**
   * Add a history of calculator
   * @param history item
   */
  public int putHistory(HistoryItem history) {
    Log.d("binCalc","historyAdd(history)");
    /* Push a history */
    histories.add(history);
    return histories.size() - 1;
  }
  
  /**
   * Add (insert and overwrite) a history of calculator
   * @param id  Insert destination Id (Later items will be removed.)
   * @param history item
   */
  public int putHistory(int id, HistoryItem history) {
    Log.d("binCalc","historyAdd(history)");
    /* Remove histories of later than it */
    while (id < histories.size()) {
      histories.remove(histories.size() - 1);
    }
    /* Push a history */
    histories.add(history);
    return histories.size() - 1;
  }
  
  /**
   * Get a history of calculator
   * @param ID of a history
   * @return history
   */
  public HistoryItem getHistory(int id) {
    if (id < histories.size()) {
      return histories.get(id);
    }
    return null;
  }
  
  public int getHistoryNums(){
    return histories.size();
  }
  
  public boolean isDecimalFraction(int nBase, String dec){
    if(dec.charAt(dec.length() -1) == '.'){ // If last char is point... (ex: "1.")
      return true;
    }
    
    if(nBase == 16){ // HEX
      if (dec.indexOf('.') == -1)
        return false;
    
    } else{ // BIN or DEC
      Double d = Double.parseDouble(dec);
      if(d % 1.0 == 0.0)
        return false; // Integer number
    }
    return true; // Fraction number
  }
  
  /**
   * Insert the digit-separator into number
   * @param number Source number string
   * @param NBase
   * @return Result number string
   */
  protected String insertSeparator(String number, int nBase) throws Exception {
    Log.d("binCalc", "Calculator.insertSeparator("+number+")");
    if (nBase == 2) { // Binary
      String r = "";
      int count = 0;
      for (int i = 0; i < number.length(); i++) {
        char c = number.charAt(i);
        if (c != '.') {
          if (count != 0 && count % 4 == 0) {
            r += " ";
          }
          count++;
        }
        r += c;
      }
      return r;
    } else if (nBase == 10) { // Decimal
      DecimalFormat formatter = new DecimalFormat("#,###");
      
      boolean is_negative = false;
      if (number.charAt(0) == '-') {
        is_negative = true;
      }
      
      if (number.indexOf(".") != -1) {
        int i = number.indexOf(".");
        String n = number.substring(0, i);
        number = formatter.format(Integer.parseInt(n)) + number.substring(i, number.length());
      } else {
        number = formatter.format(Integer.parseInt(number));
      }
      
      if (number.charAt(0) == '0' && is_negative) {
        number = "-" + number;
      }
    }
    return number;
  }
  
  /**
   * Insert space into surround a point
   * @param number
   * @return Processed number string
   */
  protected String insertSpaceForPoint(String number) {
    if (number == null || number.indexOf(".") == -1) {
      return number;
    }
    
    String r = "";
    for (int i = 0, l = number.length(); i < l; i++) {
      char c = number.charAt(i);
      if (c == '.') {
        r += "?.?";
      } else {
        r += number.charAt(i);
      }
    }
    return r;
  }
}




Java Source Code List

info.ohgita.android.bincalc.Activity_appInfo.java
info.ohgita.android.bincalc.Activity_main.java
info.ohgita.android.bincalc.Activity_preference.java
info.ohgita.android.bincalc.Adapter_BaseinputsViewPager.java
info.ohgita.android.bincalc.CalculatorBaseConvResult.java
info.ohgita.android.bincalc.CalculatorMemoryData.java
info.ohgita.android.bincalc.Calculator.java
info.ohgita.android.bincalc.Fragment_main.java
info.ohgita.android.bincalc.calculator.BaseConverterTest.java
info.ohgita.android.bincalc.calculator.BaseConverter.java
info.ohgita.android.bincalc.calculator.BasicArithOperator.java
info.ohgita.android.bincalc.calculator.ExpParserTest.java
info.ohgita.android.bincalc.calculator.ExpParser.java
info.ohgita.android.bincalc.calculator.HistoryItem.java