2014-01-06 2 views
2

Я создаю калькулятор приложение, которое работает с указанием всех шагов расчета на экране, например:Android/Java - Преобразование INT значения из уравнения удвоится

3x3x5/7 * (3/2)

И тогда пользователь просто нажимает кнопку «Ввод», чтобы получить результат.

Проблема в том, что я всегда получаю целочисленное значение в результате, что очевидно, потому что я использую целочисленные значения в вычислении (3, 5, 7 и т. Д.). Так что, если я это сделать: 1/2, то результат будет 0, но я хочу, чтобы это было так 0,5

Чтобы быть более specifcaly, это то, как работает мой калькулятор: Пользователь нажал на кнопку 5, и он появляется на экране (текстовое изображение). Затем пользователь нажимает кнопку/(деление), используя метод добавления, на экране теперь отображается 5 /, окончательно пользователь нажимает кнопку 9, а на экране отображается 5/9.
Когда пользователь нажимает «Enter», приложение получает текст с экрана и сохраняет его в переменной String, которая будет использоваться библиотекой JEXL (используется для оценки уравнений), давая мне результат.

Проблема в том, что я хочу, чтобы числа отображались на экране как целое, поэтому, если я нахожу 9, я не хочу, чтобы оно отображалось как 9.0 на экране, но есть еще одна проблема, представьте, что я хочу чтобы ввести число «93», я бы набрал 9 очков, а 9.0 появлялся, тогда я бы нажал 3, а 3.0 появлялся, давая мне «номер» 9.03.0, которого нет и не может быть используемый.

Итак, где можно преобразовать целочисленные числа в выражении String, чтобы удвоить? Или, может быть, получить двойное значение из целочисленного вычисления?

Вот мои ява файлы:

public class Main extends Activity implements OnClickListener { 

    TextView tv_screen; 
    TextView tv_set1; 
    TextView tv_set2; 

    String screenEvaluation; 
    Double screenCalculation; 
    JexlEngine jexl = new JexlEngine(); 

    static final String digits = ".*/-+^()√("; 
    static final String numbers = ""; 
    static final String operators = "*/-+"; 

    static final String shifteds = "B1"; 

    Boolean shiftPressed = false; 
    Boolean userIsInTheMiddleOfTypingANumber = false; 

    Solver solver = new Solver(); 

    DecimalFormat df = new DecimalFormat("@###########"); 
    NumberFormat nf = new DecimalFormat("#.####"); 

    //String buttonPressed; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     /* REMOVE TITLE BAR */ 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

     /* REMOVE NOTIFICATION BAR (AKA FULL SCREEN) */ 

     this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     df.setMinimumFractionDigits(0); 
     df.setMinimumIntegerDigits(1); 
     df.setMaximumIntegerDigits(8); 

     tv_screen = (TextView) findViewById(R.id.tv_screen); 
     tv_set1 = (TextView) findViewById(R.id.tv_set1); 
     tv_set2 = (TextView) findViewById(R.id.tv_set2); 

     findViewById(R.id.button_1).setOnClickListener(this); 
     findViewById(R.id.button_2).setOnClickListener(this); 
     findViewById(R.id.button_3).setOnClickListener(this); 
     findViewById(R.id.button_4).setOnClickListener(this); 
     findViewById(R.id.button_5).setOnClickListener(this); 
     findViewById(R.id.button_6).setOnClickListener(this); 
     findViewById(R.id.button_7).setOnClickListener(this); 
     findViewById(R.id.button_8).setOnClickListener(this); 
     findViewById(R.id.button_9).setOnClickListener(this); 
     findViewById(R.id.button_0).setOnClickListener(this); 

     findViewById(R.id.button_multiply).setOnClickListener(this); 
     findViewById(R.id.button_divide).setOnClickListener(this); 
     findViewById(R.id.button_minus).setOnClickListener(this); 
     findViewById(R.id.button_sum).setOnClickListener(this); 
     findViewById(R.id.button_root).setOnClickListener(this); 
     findViewById(R.id.button_power).setOnClickListener(this); 
     findViewById(R.id.button_bracket).setOnClickListener(this); 
     findViewById(R.id.button_more_less).setOnClickListener(this); 
     findViewById(R.id.button_dot).setOnClickListener(this); 

     findViewById(R.id.button_shift).setOnClickListener(this);  
     findViewById(R.id.button_enter).setOnClickListener(this); 
     findViewById(R.id.button_clear).setOnClickListener(this); 

    } 

    @Override 
    public void onClick(View v) { 

     String buttonPressed = ((Button) v).getText().toString(); 

     if (digits.contains(buttonPressed)) { 

      // digit was pressed 
      if (userIsInTheMiddleOfTypingANumber) { 

       if (buttonPressed.equals(".") && tv_screen.getText().toString().contains(".")) { 
        // ERROR PREVENTION 
        // Eliminate entering multiple decimals 
       } else { 

        if (buttonPressed.equals("()")) { 

         buttonPressed = "("; 

         if (tv_screen.getText().toString().contains("(")) { 

          buttonPressed = ")"; 

         } 

        } 

        if (buttonPressed.equals("√")) { 

         buttonPressed = "√("; 

        } 

        if (operators.contains(buttonPressed)) { 

         tv_screen.append(".0" + buttonPressed); 

        } else { 

         tv_screen.append(buttonPressed); 

        } 
       } 

      } else { 

       if (buttonPressed.equals(".")) { 
        // ERROR PREVENTION 
        // This will avoid error if only the decimal is hit before an operator, by placing a leading zero 
        // before the decimal 
        tv_screen.setText(0 + buttonPressed); 
       } else {    

        if (buttonPressed.equals("()")) { 

        buttonPressed = "("; 

         if (tv_screen.getText().toString().contains("(")) { 

          buttonPressed = ")"; 

         } 

        } 

        if (buttonPressed.equals("√")) { 

         buttonPressed = "√("; 

        } 
        tv_screen.setText(buttonPressed); 
       } 

       userIsInTheMiddleOfTypingANumber = true; 
      } 

     } else if (buttonPressed.equals("SHIFT")) { 

      if (shiftPressed == true) { 

       shiftPressed = false; 
       solver.setShift(false); 
       tv_set1.setText(""); 

      } else { 

       shiftPressed = true;  
       solver.setShift(true); 
       tv_set1.setText("SHIFT"); 

      } 

     } else if (buttonPressed.equals("ENTER")) { 

      //solver.performEnterOperation(buttonPressed); 
      //tv_screen.setText("DONE!"); 

      screenEvaluation = tv_screen.getText().toString(); 
      //screenEvaluation = screenEvaluation.replace("x", "*"); 
      screenEvaluation = screenEvaluation.replace("√(", "SQRT("); 
      Log.w("TAG", "thickness round:" + screenEvaluation); 
      Expression e = jexl.createExpression(screenEvaluation); 
      JexlContext context = new MapContext(); 
      String result = e.evaluate(context).toString(); 

      //Log.w("TAG", "thickness round:" + screenEvaluation); 

      tv_screen.setText(result); 

      userIsInTheMiddleOfTypingANumber = false;  

     } else if (shifteds.contains(buttonPressed) && shiftPressed == true) { 

      tv_set2.setText(solver.getSetTextView(buttonPressed)); 

     } else if (buttonPressed.equals("CLEAR")) { 

      userIsInTheMiddleOfTypingANumber = false; 

      tv_screen.setText("0"); 

     } else {   

      // operation was pressed 
      if (userIsInTheMiddleOfTypingANumber) { 

       //Log.w("TAG", "thickness round:" + yyy); 

       tv_set2.setText(solver.getSetTextView(buttonPressed)); 

       solver.setOperand(Double.parseDouble(tv_screen.getText().toString())); 
       userIsInTheMiddleOfTypingANumber = false; 

      } 

      //tv_set2.setText(solver.getSetTextView(buttonPressed)); 
      solver.performOperation(buttonPressed); 
      tv_screen.setText(df.format(solver.getResult())); 

     } 

    } 

} 

И это один тоже, но не используется до сих пор:

public class Solver { 

    // 3 + 6 = 9 
    // 3 & 6 are called the operand. 
    // The + is called the operator. 
    // 9 is the result of the operation. 

    private double mOperand; 
    private double mWaitingOperand; 
    private String mWaitingOperator; 
    private double mCalculatorMemory; 

    private Boolean shift; 

    private double pressure; 
    private double inner_diameter; 
    private double allowable_stress; 
    private double weld_factor; 
    private double y_factor; 
    private double corrosion; 

    // operator types 
    public static final String ADD = "+"; 
    public static final String SUBTRACT = "-"; 
    public static final String MULTIPLY = "x"; 
    public static final String DIVIDE = "/"; 

    public static final String CLEAR = "C" ; 
    public static final String CLEARMEMORY = "MC"; 
    public static final String ADDTOMEMORY = "M+"; 
    public static final String SUBTRACTFROMMEMORY = "M-"; 
    public static final String RECALLMEMORY = "MR"; 
    public static final String SQUAREROOT = "√"; 
    public static final String SQUARED = "x²"; 
    public static final String INVERT = "1/x"; 
    public static final String TOGGLESIGN = "+/-"; 
    public static final String SINE = "sin"; 
    public static final String COSINE = "cos"; 
    public static final String TANGENT = "tan"; 

    public static final String ARC = "ARC"; 
    public static final String B1 = "B1"; 
    public static final String B2 = "B2"; 
    public static final String B3 = "B3"; 
    public static final String B4 = "B4"; 
    public static final String B5 = "B5"; 
    public static final String B6 = "B6"; 

    // public static final String EQUALS = "="; 

    // constructor 
    public Solver() { 
     // initialize variables upon start 
     mOperand = 0; 
     mWaitingOperand = 0; 
     mWaitingOperator = ""; 
     mCalculatorMemory = 0; 

     shift = false; 

     pressure = 0; 
     inner_diameter = 0; 
     allowable_stress = 0; 
     weld_factor = 0; 
     y_factor = 0; 
     corrosion = 0; 
    } 

    public void setOperand(double operand) { 
     mOperand = operand; 
    } 

    public double getResult() { 
     return mOperand; 
    } 

    // used on screen orientation change 
    public void setMemory(double calculatorMemory) { 
     mCalculatorMemory = calculatorMemory; 
    } 

    // used on screen orientation change 
    public double getMemory() { 
     return mCalculatorMemory; 
    } 

    public String toString() { 
     return Double.toString(mOperand); 
    } 

    public void setShift(Boolean shiftState) {  
     shift = shiftState;  
    } 

    public void setPressure(double setPressure) { 
     pressure = setPressure; 
    } 

    public void setInnerDiameter(double setInnerDiameter) { 
     inner_diameter = setInnerDiameter; 
    } 

    public void setAllowableStress(double setAllowableStress) { 
     allowable_stress = setAllowableStress; 
    } 

    public void setWeldFactor(double setWeldFactor) { 
     weld_factor = setWeldFactor; 
    } 

    public void setYFactor(double setYFactor) { 
     y_factor = setYFactor; 
    } 

    public void setCorrosion(double setCorrosion) { 
     corrosion = setCorrosion; 
    } 

    public String getSetTextView(String setText) { 

     String text; 

     if (setText.equals(ARC)) {   
      text = "PIPE";   
      return text;   
     } else if (setText.equals(B1)) { 
      text = "PRESSURE";   
      return text; 
     } else if (setText.equals(B2)) { 
      text = "INNER DIAMETER";   
      return text;   
     } else if (setText.equals(B3)) { 
      text = "ALLOWABLE STRESS";   
      return text; 
     } else if (setText.equals(B4)) { 
      text = "WELD FACTOR";   
      return text; 
     } else if (setText.equals(B5)) { 
      text = "Y FACTOR";   
      return text; 
     } else if (setText.equals(B6)) { 
      text = "CORROSION"; 
      return text; 
     } 

     text = "NADA";  
     return text; 

    } 

    public double pipeThickness(double inner_pressure, double allowable_stress, double weld_factor, double inner_diameter, double corrosion, double y_factor) {  

     double thickness = ((inner_pressure * inner_diameter) + (2* allowable_stress * weld_factor * corrosion) 
       + (2 * y_factor * inner_pressure * corrosion))/(2* ((allowable_stress * weld_factor) 
       + (inner_pressure * y_factor) - inner_pressure)); 

     return thickness; 

    } 

    protected void performEnterOperation(String operator) { 

     if (shift == true) { 

      if (operator.equals(B1)) { 

       setPressure(mOperand); 

      } 

     } 

    } 

    protected double performOperation(String operator) { 

     /* 
     * If you are using Java 7, then you can use switch in place of if statements 
     * 
     *  switch (operator) { 
     *  case CLEARMEMORY: 
     *   calculatorMemory = 0; 
     *   break; 
     *  case ADDTOMEMORY: 
     *   calculatorMemory = calculatorMemory + operand; 
     *   break; 
     *  etc... 
     *  } 
     */ 

     if (shift == true) { 

      if (operator.equals(ARC)) { 

       getSetTextView(ARC); 
       mOperand = 25.0; 

      } 

     } else { 

      if (operator.equals(CLEAR)) { 
       mOperand = 0; 
       mWaitingOperator = ""; 
       mWaitingOperand = 0; 
       // mCalculatorMemory = 0; 
      } else if (operator.equals(CLEARMEMORY)) { 
       mCalculatorMemory = 0; 
      } else if (operator.equals(ADDTOMEMORY)) { 
       mCalculatorMemory = mCalculatorMemory + mOperand; 
      } else if (operator.equals(SUBTRACTFROMMEMORY)) { 
       mCalculatorMemory = mCalculatorMemory - mOperand; 
      } else if (operator.equals(RECALLMEMORY)) { 
       mOperand = mCalculatorMemory; 
      } else if (operator.equals(SQUAREROOT)) { 
       mOperand = Math.sqrt(mOperand); 
      } else if (operator.equals(SQUARED)) { 
       mOperand = mOperand * mOperand; 
      } else if (operator.equals(INVERT)) { 
       if (mOperand != 0) { 
        mOperand = 1/mOperand; 
       } 
      } else if (operator.equals(TOGGLESIGN)) { 
       mOperand = -mOperand; 
      } else if (operator.equals(SINE)) { 
       mOperand = Math.sin(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees 
      } else if (operator.equals(COSINE)) { 
       mOperand = Math.cos(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees 
      } else if (operator.equals(TANGENT)) { 
       mOperand = Math.tan(Math.toRadians(mOperand)); // Math.toRadians(mOperand) converts result to degrees      
      } else { 
       performWaitingOperation(); 
       mWaitingOperator = operator; 
       mWaitingOperand = mOperand; 
      } 

     } 

     return mOperand;   

    } 

    protected void performWaitingOperation() { 

     if (mWaitingOperator.equals(ADD)) { 
      mOperand = mWaitingOperand + mOperand; 
     } else if (mWaitingOperator.equals(SUBTRACT)) { 
      mOperand = mWaitingOperand - mOperand; 
     } else if (mWaitingOperator.equals(MULTIPLY)) { 
      mOperand = mWaitingOperand * mOperand; 
     } else if (mWaitingOperator.equals(DIVIDE)) { 
      if (mOperand != 0) { 
       mOperand = mWaitingOperand/mOperand; 
      } 
     } 

    } 
} 

Ну, решение, которое я нашел это:

if (operators.contains(buttonPressed)) {  

         tempNumber = Double.parseDouble(tv_screen.getText().toString().replace(tempString, "")); 
         equation = equation + tempNumber.toString() + buttonPressed;      
         tempString = tv_screen.getText().toString() + buttonPressed; 

        } 

Я создал 3 переменные: Двойной tempNumber, который получит значения с экрана и d храните его как двойное. Строковое уравнение, которое сохранит уравнение как String с двойными значениями, поэтому «9 * 3» будет «9.0 * 3.0». String tempString, который используется для «очистки» переменной tempNumber, заменяя «x», «/» и т. Д. С помощью «» (ничего), поэтому он преобразует только числа в двойные.

Финли, я буду вместо того, чтобы уравнение с экраном TextView, я достану из переменного уравнения:

tempNumber = Double.parseDouble(tv_screen.getText().toString().replace(tempString, "")); 
equation = equation + tempNumber.toString(); 
Expression e = jexl.createExpression(equation); 
JexlContext context = new MapContext(); 
String result = e.evaluate(context).toString(); 

Во всяком случае, спасибо всем за ваше время!

+0

Если вы действительно хотите сделать приложение для калькулятора, вам нужно использовать BigDecimal вместо double: /, вам нужно будет реорганизовать какой-то код, но будет делать именно то, что вы хотите ... – GhostDerfel

+0

Возможно, вам стоит рассмотреть возможность использования окончательной строки, которую вы объявили в классе Solver для операторов (т. е. «√») вместо проверки равенства для них в первом классе, который вы опубликовали. Гораздо более читабельны, меньше шансов опечаток. – turbo

+0

@GhostDerfel, спасибо за ваш комментарий, я прочитаю о BigDecimal, чтобы узнать, соответствует ли он моим потребностям. – xadun

ответ

4

Если вы хотите, чтобы разобрать двойной из строки вы можете использовать

Double.parseDouble(sValue); 

Вы также можете использовать преобразование explisit в линии для уравнения, так что вы можете сделать что-то как:

(double)inum*(double)inum1*(double)inum2/(double)inum4*((double)inum5/(double)inum6) 

и ваш результат должен затем выйти, как двойной вместо целого

+0

Я не могу преобразовать каждое число, которое пользователь ударил, потому что произошла следующая ошибка: Пользователь хочет ввести «93». Сначала он наберет «9», приложение преобразует его в двойное, а затем «9.0» появится на экране. Итак, теперь он вводит «3», приложение конвертирует его в двойное, а затем, когда приложение использует метод append, на экране появится следующее: «9.03.0». К сожалению, я не могу использовать Double.parseDouble() в целом выражении, например, Double.parseDouble ("3 * 3/5"). =/ – xadun

+0

Нет. Я имел в виду, что вы делаете, храня их все целые числа, как обычно, а затем, когда вы идете, чтобы проанализировать их уравнение. Не разбирайте их, поскольку они нажаты, потому что тогда это будет показано таким образом. Вы также можете использовать truncate для вашего представления, чтобы все рассматривалось как int, но переменные все двойки. Просто все предложения. – w9jds

+0

О, я понимаю сейчас! Но я нашел другую проблему, библиотека JEXL получает выражение из строковой переменной, а затем оценивает ее, чтобы найти ответ. Приложение получает переменную String с экрана (textview), поэтому, если на экране отображается «9 * 9», это то, что библиотека JEXL будет использовать для генерации ответа. Таким образом, не имеет значения, сохранены ли переменные как двойные, если они отображаются как целые числа на экране. Возможно, было бы легко использовать систему RPN (см. Калькуляторы HP)! haha – xadun

0

Это поможет, если все ваши номера имеют тип double, особенно ваш ответ. для принудительного двойного ответа, используйте приведение типов или умножение на 1.0 при выполнении деления и умножения. (буквально «1.0" , а не только „1“)

+0

Ну, я не могу использовать double, поскольку пользователь вводит числа, как я объяснил в комментарии @ w9jds. И бессмысленно преобразовать результат (который будет целочисленным), чтобы удвоить, поскольку я потерял бы точность. =/ – xadun

+0

Я бы дал аналогичное объяснение, которое было дано там. Используйте значения только в качестве удвоений, когда дело доходит до вычислений. В противном случае сохраните строку или все, что вам нужно, чтобы ваш дисплей выглядел правильно. :) – Drifter64

-1

Java по умолчанию поддерживает целочисленную арифметику Чтобы получить тыс.. e в float или double (значения десятичной точки), мы должны выполнить операцию по типу с плавающей точкой или двойному типу. для например:

double x = 3.0/2.0 

даст вам х, как 1,5 :) но

double x = 3/2 

даст вам , которые вы не предпочли в этом случае :( Надеюсь, вам это поможет

+0

Прочтите мой комментарий в комментарии @ w9jds. знак равно – xadun

Смежные вопросы