I have calculate and display result of trigonometric function on android app - android

When i click on digit button on app and then on cos for example, works fine.
When i click on cos and number, return -1.
For example on display TextView i see:
1cos
0.540302320
if i put:
cos1
-1
I use a switch case.
private double operateAritmetic(String a, String b, String op){
switch (op){
case "+": return (Double.valueOf(a) + Double.valueOf(b));
case "-": return (Double.valueOf(a) - Double.valueOf(b));
case "*": return (Double.valueOf(a) * Double.valueOf(b));
case "/": try{
return (Double.valueOf(a) / Double.valueOf(b));
}catch (Exception e){Log.d("Calc",e.getMessage());
}
default: return -1;
}
}
private double operateTrigonometric(String a, String op){
switch (op){
case "Sin":
return(Math.sin(Double.valueOf(a)));
case "Cos":
return(Math.cos(Double.valueOf(a)));
case "Tan":
try{
return(Math.tan(Double.valueOf(a)));
}catch(Exception e){
Log.d("Calc", e.getMessage());
}
case "sqrt":
return(Math.sqrt(Double.valueOf(a)));
default: return -1;
}
}
public void onClickEqual(View v){
String[] operation=display.split(Pattern.quote(currentOperator));
Double result;
if(operation.length==1) {
result = operateTrigonometric(operation[0],currentOperator);
_screen.setText(display + "\n" + String.valueOf(result));
}
else if (operation.length<2)
return;
else {
result = operateAritmetic(operation[0], operation[1], currentOperator);
_screen.setText(display + "\n" + String.valueOf(result));
}
}

Related

Android Studio Java infix to postfix calculations decimal point gives crash

I was trying to make a calculator for my university homework. to calculate the results I use infix to postfix convention. but this code doesn't take only decimal point (.) as a result, it crashes whenever I put (.) as input like 1.1+ it crashes. In the operator section there is no part for decimal point this is happening for that. but I was confused about how to resolve this.
run log!
class Solution {
public double calculate(String s) {
if (s == null || s.length() < 1) return Integer.MIN_VALUE;
return evalSuffix(inToSuffix(s));
}
public int rank(Character op) {
switch (op) {
case '+': return 1;
case '-': return 1;
case '*': return 2;
case '/': return 2;
case '%': return 2;
case '^': return 3; //you can add more operators
default: return 0; //priority for '('
}
}
public List<Object> inToSuffix(String s) {
Stack<Character> opStack = new Stack<>();
List<Object> suffix = new LinkedList<>();
double num = 0;
boolean numCached = false;
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
numCached = true;
}
else {
if (numCached) {
suffix.add(num);
num = 0;
numCached = false;
}
if (c == ' ' || c == '\t') continue;
if (c == '(') opStack.push('(');
else if (c == ')') {
while (opStack.peek() != '(') suffix.add(opStack.pop()); //op in () should be added first
opStack.pop();
}
else {
while (!opStack.isEmpty() && rank(c) <= rank(opStack.peek())) suffix.add(opStack.pop());
opStack.push(c);
}
}
}
if (numCached) suffix.add(num);
while (!opStack.isEmpty()) suffix.add(opStack.pop());
return suffix;
}
public double evalSuffix(List<Object> suffix) {
Stack<Double> numStack = new Stack<>();
double num1 = 0;
double num2 = 0;
for (Object o : suffix) {
if (o instanceof Character) {
char op = (Character)o;
num2 = numStack.pop();
num1 = numStack.pop();
switch (op) {
case '+': numStack.push(num1 + num2); break;
case '-': numStack.push(num1 - num2); break;
case '*': numStack.push(num1 * num2); break;
case '/': numStack.push(num1 / num2); break;
case '%': numStack.push(num1 % num2); break;
case '^': numStack.push((double)Math.pow((double)num1, (double)num2)); break;
}
}
else numStack.push((Double) o);
}
return numStack.pop();
}
}
Also, you can provide a better solution if you have any!!
This works fine for m!~
ExpCalculator{
public static double evalPostfix(String postfixExp){
int index = 0;
Stack<Double> arr = new Stack<Double>();
double result = 0;
for(int i = 0; i < postfixExp.length(); i++)
{
char c = postfixExp.charAt(i);
if(c == ' ')
continue;
else if(Character.isDigit(c))
{
double x = 0.0;
boolean check = true;
while(Character.isDigit(c) || c == '.')
{
if(c!= '.' && check == true){
x = x*10 + (double)(c-'0');
i++;
c = postfixExp.charAt(i);
}
else{
check = false;
x = x + 0.1 + (double)(c-'0')/10;
i++;
c = postfixExp.charAt(i);
}
}
i--;
arr.push(x);
}
else
{
double val1 = arr.pop();
double val2 = arr.pop();
switch(c)
{
case '+':
arr.push(val2+val1);
break;
case '-':
arr.push(val2- val1);
break;
case '/':
if (val1 == 0)throw new ArithmeticException();
arr.push(val2/val1);
break;
case '*':
arr.push(val2*val1);
break;
case '^':
for(int x = 1; x< val1; x++)val2*=val2;
arr.push(val2);
break;
default:
throw new ArithmeticException();
}
}
}
return arr.pop();
}
public static String infixToPostfix(String exp){
String result = "";
Stack<Character> arr = new Stack<>();
for (int i = 0; i <exp.length() ; i++) {
char c = exp.charAt(i);
if(precedence(c)>0){
while(arr.isEmpty()==false && precedence(arr.peek())>=precedence(c)){
result += arr.pop();
}
result += ' ';
arr.push(c);
}else if(c==')'){
char x = arr.pop();
while(x!='('){
result += x;
x = arr.pop();
}
}else if(c=='('){
arr.push(c);
}else{
result += c;
}
}
for (int i = 0; i <=arr.size() ; i++) {
result += arr.pop();
}
return result;
}
static int precedence(char c){
switch (c){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
}

getting NumberFormatException: s == null after clicking button

I'm newbie in android. After clicking this button(when nothing is in TextView i.e. it shows "" ) I'm getting NumberFormatException but in other cases it is working .I want to show toast message if nothing is in the String and my TextView initially is
android:id="#+id/text_view_result"
android:text=""
that button is
buttonExpense.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Integer.valueOf(result) < 0) {
Toast.makeText(getActivity().getApplicationContext(), "Amount can't be negative", Toast.LENGTH_SHORT).show();
return;
}
else if (Integer.valueOf(result) > 0) {
Intent intent = new Intent(fa2, EditorActivity.class);
intent.putExtra("result", result);
startActivity(intent);
}
else if(Integer.valueOf(result) == 0) {
Toast.makeText(getActivity().getApplicationContext(), "Amount can't be 0", Toast.LENGTH_SHORT).show();
return;
}
else{
Toast.makeText(getActivity().getApplicationContext(), "Please enter your amount", Toast.LENGTH_SHORT).show();
return;
}
}
});
method where result String is used is in method as given below
private void onEqualButtonClicked() {
int res = 0;
try {
int number = Integer.valueOf(tmp);
int number2 = Integer.valueOf(resultTextView.getText().toString());
switch (operator) {
case "+":
res = number + number2;
break;
case "/":
res = number / number2;
break;
case "-":
res = number - number2;
break;
case "X":
res = number * number2;
break;
}
result = String.valueOf(res);
resultTextView.setText(result);
}
catch (Exception e) {
e.printStackTrace();
}
An empty string is not a number. What you want to do is check if it's a number first and then handle it.
int number;
try {
number = Integer.parseInt(result);
} catch (NumberFormatException exception) {
// handle case where it's not a number
}
// perform logic where it is a number

A simple calculator

I'm new to Android. I'm trying to develop my first calculator. My calculator output is good, but I'm trying to make some changes to it. Please suggest. My output is 2+2=4.0 How can I get 4 if I put 2+2 and 4.0 when I put 2.8+1.2.
Also, please help me out in trying to figure out how can i keep on adding till i press =.
My code that I'm looking at is below:
private View.OnClickListener buttonClickListerner = new
View.OnClickListener() {
float r;
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.clear:
screen.setText("");
operator.setText("");
FirstNum= 0;
showtext.setText("");
break;
case R.id.buttonAdd:
mMath("+");
operator.setText("+");
showtext.setText(String.valueOf(FirstNum));
break;
case R.id.buttonMinus:
mMath("-");
operator.setText("-");
break;
case R.id.buttonMul:
mMath("*");
operator.setText("*");
break;
case R.id.buttonequal:
mResult();
break;
case R.id.buttonDiv:
mMath("/");
operator.setText("/");
break;
case R.id.buttonPercent:
mMath("%");
r = FirstNum / 100;
showtext.setText("[" + String.valueOf(FirstNum) + "%" + "]");
screen.setText(String.valueOf(r));
break;
default:
String num = ((Button) v).getText().toString();
getKeyboard(num);
break;
}
}
};
public void mMath(String str){
FirstNum = Float.parseFloat(screen.getText().toString());
operation = str;
screen.setText("");
}
public void getKeyboard(String str){
String CurrentScreen = screen.getText().toString();
if(CurrentScreen.equals("0"))
CurrentScreen = "";
CurrentScreen = CurrentScreen + str;
screen.setText(CurrentScreen);
String ExScreen = CurrentScreen;
screen.setText(ExScreen);
}
public void mResult(){
float SecondNum = Float.parseFloat(screen.getText().toString());
float ThirdNum = Float.parseFloat(screen.getText().toString());
float result = 0;
//float exresult = result;
if(operation.equals("+")){
result = FirstNum + SecondNum;
// exresult = result + ThirdNum;
}
if(operation.equals("-")){
result = FirstNum - SecondNum;
//exresult = result - ThirdNum;
}
if(operation.equals("*")){
result = FirstNum * SecondNum;
//exresult = result * ThirdNum;
}
if(operation.equals("/")){
result = FirstNum / SecondNum;
//exresult = result / ThirdNum;
}
screen.setText(String.valueOf(result));
//screen.setText(String.valueOf(exresult));
showtext.setText(String.valueOf(FirstNum + operation + SecondNum));
//showtext.setText(String.valueOf(FirstNum + operation + SecondNum +
operation + ThirdNum));
}
}
I guess you should do your calculations as double and then before setting the output to TextView (or whatever you are using), check for the output if int or not and then decide which form of output to set to the TextView.
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
// integral type
}
See this
Edit:
The idea is to check that fractional part of the number is 0 (i.e.) the number is integer.
You may also Use these conditions [if true then variable is an Integer]
// check if
variable == Math.ceil(variable)
or
// check if
variable == Math.round(variable)
Also Math.round(float f) will return the interger form of the number!
To add multiple item first set up an array with a size of how long the user can input and then loop through each array adding them equivalently... i know this is a vague answer but you can ask me if anything is unclear and also an up vote would be nice. you got the right idea for the cases just try the following code
// array to sum
int[] numbers = new int[]{ 10, 10, 10, 10};
int sum = 0;
for (int i=0; i < numbers.length ; i++) {
sum = sum + numbers[i];
}
System.out.println("Sum value of array elements is : " + sum);
}

How to regularly update an an integer

So I have a String[] which contains math expressions like "3+6=" or "5+9/8=".
I have a function that gets the array, loops through the array and while looping, it splits the array so that I have one String[] containing the math operations like +,-,*,/ and another int[] containing the numbers in the question.
The function then puts the the answer into a int[] called answers. My question is that why when I output the answers[0], I can only see the first number and not the answer to the first question?
EDIT = I have found out that where the problem is happening. It is happening in my evaluation method. I dont know why:
public int evaluateAnswerTwoOperations(String operation, int numberOne, int numberTwo) {
switch(operation){
case "+":
Log.d("usingsubtraction","plus2nmbers");
return numberOne + numberTwo;
case "-":
Log.d("usingsubtraction","usingsubtraction");
return numberOne - numberTwo;
case "/":
Log.d("usingsubtraction","usingdivision");
return numberOne / numberTwo;
default:
Log.d("usingsubtraction","usingmultiplication");
return numberOne*numberTwo;
}
Something like this:
import android.util.Log;
public class TwoNumberOperation {
private final String PLUS = "+";
private final String MINUS = "-";
private final String MULTIPLY = "*";
private final String DIVIDE = "/";
private final String EQUAL = "=";
private String operation;
private int numberOne;
private int numberTwo;
public TwoNumberOperation(String operation, int numberOne, int numberTwo) {
if (operation.equalsIgnoreCase(PLUS) ||
operation.equalsIgnoreCase(MINUS) ||
operation.equalsIgnoreCase(MULTIPLY) ||
operation.equalsIgnoreCase(DIVIDE)) {
this.operation = operation;
this.numberOne = numberOne;
this.numberTwo = numberTwo;
}
else {
Log.d("error", "error: invalid operation");
this.operation = "";
this.numberOne = 0;
this.numberTwo = 0;
}
}
public int getAnswer() {
switch (operation) {
case PLUS:
Log.d("addition", "addition");
return numberOne + numberTwo;
case MINUS:
Log.d("subtraction", "subtraction");
return numberOne - numberTwo;
case MULTIPLY:
Log.d("multiplication", "multiplication");
return numberOne / numberTwo;
case DIVIDE:
Log.d("division", "division");
return numberOne / numberTwo; // note the returning an int
default:
Log.d("error", "error");
return -999999999;
}
}
#Override
public String toString() {
return numberOne + operation + numberTwo + EQUAL;
}
}

EditText set selector position doesn't works

When I delete text inside EditText with clrFunc() I lost cursor (I see it flashing, but nothing happens if I type). I can't type back in. I have to click back onEditText and then I can type in.
/* WORKS PERFECT */
private void delFunc(){
String str = display.getText().toString();
if(str.length() > 0){
String strStart = str.substring(0, SELECTOR_POSITION-1);
String strEnd = str.substring(SELECTOR_POSITION);
display.setText(strStart + strEnd);
display.requestFocus();
display.setSelection(--SELECTOR_POSITION);
}
}
/* NOT FULLY WORKING */
private void clrFunc(){
display.setText(""); //text is set to ""
display.requestFocus(); //not working
display.setSelection(display.getText().length()); //not working
}
EDIT: Added more code, I'm building simple calculator.
private EditText display;
private Button b0, b1, b2, b3, b4, b5, b6, b7, b8, b9;
private Button bDec, bEquals, bAdd, bSub, bMultiply, bDivide, bClear, bBracket, bBackBracket, bDel, bClrH;
private Button bSin, bAsin, bCos, bAcos, bTan, bAtan, bLn, bLog, bPow, bPow2, bSqrt, bPi, bE, bToRad, bToDeg;
private TextView history;
private int SELECTOR_POSITION;
private void implementGUI(){
/* EditText */
display = (EditText) findViewById(R.id.etDisplay);
display.setOnTouchListener(this);
/* ... */
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.bZero: insert("0"); break;
case R.id.bOne: insert("1"); break;
case R.id.bTwo: insert("2"); break;
case R.id.bThree: insert("3"); break;
case R.id.bFour: insert("4"); break;
case R.id.bFive: insert("5"); break;
case R.id.bSix: insert("6"); break;
case R.id.bSeven: insert("7"); break;
case R.id.bEight: insert("8"); break;
case R.id.bNine: insert("9"); break;
case R.id.bDecPoint: insert("."); break;
case R.id.bAdd: insert("+"); break;
case R.id.bSub: insert("-"); break;
case R.id.bMultiply: insert("*"); break;
case R.id.bDivide: insert("/"); break;
case R.id.bBracket: insert("("); break;
case R.id.bBackBracket: insert(")"); break;
case R.id.bDel: delFunc(); break;
case R.id.bC: clrFunc(); break;
case R.id.bEquals: calcFunc(); break;
case R.id.bClrH: clrHistory(); break;
case R.id.bSin: insert("sin("); break;
case R.id.bAsin: insert("asin("); break;
case R.id.bCos: insert("cos("); break;
case R.id.bAcos: insert("acos("); break;
case R.id.bTan: insert("tan("); break;
case R.id.bAtan: insert("atan("); break;
case R.id.bLn: insert("ln("); break;
case R.id.bLog: insert("log("); break;
case R.id.bPow: insert("^"); break;
case R.id.bPow2: insert("^2"); break;
case R.id.bSqrt: insert("sqrt("); break;
case R.id.bPi: insert("(PI)"); break;
case R.id.bE: insert("(E)"); break;
case R.id.bToRad: insert("toRadians("); break;
case R.id.bToDeg: insert("toDegrees("); break;
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
v.onTouchEvent(event);
InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
SELECTOR_POSITION = display.getSelectionStart();
return true;
}
private void delFunc(){
String str = display.getText().toString();
if(str.length() > 0){
String strStart = str.substring(0, SELECTOR_POSITION-1);
String strEnd = str.substring(SELECTOR_POSITION);
display.setText(strStart + strEnd);
display.requestFocus();
display.setSelection(--SELECTOR_POSITION);
}
}
/* NOT FULLY WORKING */
private void clrFunc(){
display.setText("");
display.requestFocus();
display.setSelection(display.getText().length());
}
private void clrHistory(){
history.setText("");
}
private void calcFunc(){
try{
MathEval math = new MathEval();
String input = display.getText().toString();
history.setText(String.format("%s = %s%n%s", input, math.evaluate(input), history.getText()));
}catch(Exception e){
e.printStackTrace();
history.setText(String.format("%s%n%s", "ERROR", history.getText()));
}
clrFunc();
}
private void insert(String midStr){
try{
String input = display.getText().toString();
String startStr = input.substring(0,SELECTOR_POSITION);
String endStr = input.substring(SELECTOR_POSITION);
String retStr = startStr + midStr + endStr;
SELECTOR_POSITION += midStr.length();
display.setText(retStr);
display.setSelection(SELECTOR_POSITION);
}catch(Exception e){
e.printStackTrace();
}
}
P.S.: Sorry for my bad language.
If you want to directly type into the EditText you are missing the following in your method:
display.requestFocus();
EDIT
This is the method I am using to show the keyboard with focus, the different focus call could do the trick.
protected void showKeyboard(EditText edit) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, 0);
edit.requestFocusFromTouch();
}

Categories

Resources