1 Attachment(s)

Using functions in a calculator

I'm writing a calculator program for fun that takes an input from a user, via typed commands. So far, it works very well with basic ^*/+- arithmetic, however, I want to start adding functions, such as sin(45) or ln(e) and, eventually, variables to the expressions it solves. How would one do that? I don't have any code for that purpose as I don't know how or where to start for that. If there is some code you'd like to see that would help, please ask for it, as I don't know what would help and there is too much code to post it all.

Attached is what I have now.Attachment 2479

Re: Using functions in a calculator

Review the Math class for the functions already available. Apache has some libraries that also provide these math functions. While I think the core Java Math class will have everything you need, using an Apache library could be a good learning experience in using 3rd party libraries.

Re: Using functions in a calculator

I know how to use the Math class and have used third party libraries in the past for mathematical purposes. My question is how to solve those functions inside of an expression, ie 3+sin(2pi)^(-3). The Math library only makes solving the functions themselves easier, but not detecting them as functions, sorting them, and then going throw and solving them. The solving part is what I can do.

Re: Using functions in a calculator

Are you asking how to parse the statement: 3+sin(2pi)^(-3)

Re: Using functions in a calculator

It sounds like it's the solving part you CAN do, but it's parsing the user's commands into the correct formulas that has you stumped. This is a common early project, so try searching for "java console calculator" or similar. If you want help with specific code or attempts you've made to do this, then post that code in code tags and describe what help you need, ask specific questions.

Re: Using functions in a calculator

Norm, yes, at least, just the sin(2pi) part.

Re: Using functions in a calculator

Math.sin( 2 * Math.PI ) ?

But if you know how to use the Math class as you said in post #3, this should already be familiar to you, so I'm still missing something.

Re: Using functions in a calculator

Is there an operator missing between the 2 and pi?

What syntax rules are there for that expression? For example:

The () are delimiters.

The method name comes before the (

the args for the method come before the )

Re: Using functions in a calculator

OK, let's slow down here. Here's how I parse equations right now, minus functions and variables (why I'm here).

1. Take an input expression

2. Set up the equation for input into the parser

- get rid of space characters

- replace "--" with "+"

- detect negative values and replace them with (0-value)

3. Send to the parser

- convert the equation from infix to postfix (RPN notation)

4. Simplify the postfix expression

- I'll post the code for the simplification algorithm

Here's what I don't know how to do:

1. how to interpret when a user inputs a function into the input

2. where/how to parse it

3. when to solve the called functions (sin, cos, tan, etc...)

Here's what I do know:

1. simplifying and parsing basic arithmetic

2. how to evaluate the called functions (Math.sin(2*Math.PI) I understand)

Here's how I evaluate/simplify expressions:

Code java:

public static String convertToPostfix(String infix) {
// Return a postfix representation of the expression in infix.
Stack operatorStack = new Stack(); // the stack of operators
char c; // the first character of a token
StringTokenizer parser = new StringTokenizer(infix,"+-*/^() ",true);
// StringTokenizer for the input string
StringBuffer postfix = new StringBuffer(infix.length()); // result
// Process the tokens.
while (parser.hasMoreTokens()) {
String token = parser.nextToken(); // get the next token
// and let c be
c = token.charAt(0); // the first character of this token
if ( (token.length() == 1) && isOperator(c) ) { // if token is
// an operator
while (!operatorStack.empty() &&
!lowerPrecedence(((String)operatorStack.peek()).charAt(0), c))
// (Operator on the stack does not have lower precedence, so
// it goes before this one.)
postfix.append(" ").append((String)operatorStack.pop());
if (c==')') {
// Output the remaining operators in the parenthesized part.
String operator = (String)operatorStack.pop();
while (operator.charAt(0)!='(') {
postfix.append(" ").append(operator);
operator = (String)operatorStack.pop();
}
}
else
operatorStack.push(token);// Push this operator onto the stack.
}
else if ( (token.length() == 1) && isSpace(c) ) { // else if
// token was a space
; // ignore it
}
else { // (it is an operand)
postfix.append(" ").append(token); // output the operand
}//end if
}// end while for tokens
// Output the remaining operators on the stack.
while (!operatorStack.empty())
postfix.append(" ").append((String)operatorStack.pop());
// Return the result.
return postfix.toString();
}//end convertToPostfix
//Evaluate and simplify
public static String simplify(String equ)
{
//System.out.println(equ);
equ = convertToPostfix(equ);//convert to post fix
//System.out.println(equ);
int index = 0;
while(equ.endsWith("+")||equ.endsWith("-")|| equ.endsWith("*")|| equ.endsWith("/")|| equ.endsWith("^")) //while there are still unsolved operators
{
index = 0;//start all the way to the left
while((!isOperator(equ.charAt(index))/*||
minusThatIsNegative(equ,index)*/)&&
index<equ.length()-1)//search for first operator
{
index++;
if(minusThatIsNegative(equ,index))
{
index++;
}
}
//find location of previous two numbers
//numbers will be three spaces back
int spaces = 0;
int search = index;
while(spaces<3&&search>0)
{
if(isSpace(equ.charAt(search)))
spaces++;
search--;
}
String expr = equ.substring(search+1,index+1).trim();//copy numbers and operator to a string
BigDecimal number1,number2;//find the first and second number
System.out.println(":"+expr+":");
search = 0;
while(!isSpace(expr.charAt(search)))//finds first number
{
search++;
}
System.out.println(":" + expr.substring(0, search+1).trim()+":");
number1 = new BigDecimal(expr.substring(0, search+1).trim());//sets it to a string
System.out.println("search = " + search);
number2 = new BigDecimal(expr.substring(search, expr.length()-1).trim());//sets the second number to a string
//System.out.println(number1 +"; " + number2);
String combine = "";//evaluates the problem
if(expr.endsWith("^"))
{
combine = Double.toString(Math.pow(number1.doubleValue(), number2.doubleValue()));
}
else if(expr.endsWith("*"))
{
combine = number1.subtract(number2).toString();
}
else if(expr.endsWith("/"))
{
try{
combine = number1.divide(number2,10, RoundingMode.HALF_EVEN).toString();
}catch(ArithmeticException e)
{
return "Error: cannot divide by zero.";
}
}
else if(expr.endsWith("+"))
{
combine = number1.add(number2).toString();
}
else if(expr.endsWith("-"))
{
combine = number1.subtract(number2).toString();
}
equ = equ.replace(expr, combine);
System.out.println("equ = " + equ + "\n");
}
return equ;
}
public static boolean isOperator(char c) { // Tell whether c is an operator.
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c=='(' || c==')';
}//end isOperator
public static boolean isSpace(char c) { // Tell whether c is a space.
return (c == ' ');
}//end isSpace
public static boolean isNumber(char c) {
return c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9'||c=='0'||c=='.';
}
public static boolean minusThatIsNegative(String expr, int indexOfMinus)
{
if(indexOfMinus >= expr.length()-2)
return false;
if(expr.charAt(indexOfMinus)!='-')
return false;
else if(!isNumber(expr.charAt(indexOfMinus+1)))
return false;
else
return true;
}

Re: Using functions in a calculator

Quote:

when a user inputs a function into the input

That has to do with the syntax rules. See post#8.