Java strings are converted into arithmetic expressions to calculate and output the results. This tool can directly calculate arithmetic expressions in the form of strings, and it is very simple to use.
This tool contains two classes Calculator and ArithHelper
Calculator code is as follows:
import java.util.Collections;import java.util.Stack;/** * Arithmetic expression evaluation* Directly call Calculator's class method conversion() * Passing in an arithmetic expression will return a floating-point value result* If the calculation process is incorrect, a NaN will be returned */public class Calculator {private Stack<String> postfixStack = new Stack<String>();// Suffix stack private Stack<Character> opStack = new Stack<Character>();// Operator stack private int[] operatorPriority = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };// Operator priority using operator ASCII code-40 for indexing public static double conversion(String expression) {double result = 0;Calculator cal = new Calculator();try {expression = transform(expression);result = cal.calculate(expression);}catch (Exception e) {// e.printStackTrace();// Operation error returns NaNreturn 0.0 / 0.0;}// return new String().valueOf(result);return result;}/** * Change the symbol of negative numbers in the expression* * @param expression * For example -2+-1*(-3E-2)-(-1) is converted to ~2+~1*(~3E~2)-(~1) * @return */private static String transform(String expression) {char[] arr = expression.toCharArray();for (int i = 0; i < arr.length; i++) {if (arr[i] == '-') {if (i == 0) {arr[i] = '~';} else {char c = arr[i - 1];if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {arr[i] = '~';}}}}if(arr[0]=='~'|| arr[1]=='('){arr[0]='-';return "0"+new String(arr);} else{return new String(arr);}}/** * Calculate according to the given expression* * @param expression * The expression to be calculated for example: 5+12*(3+5)/7 * @return */public double calculate(String expression) {Stack<String> resultStack = new Stack<String>();prepare(expression);Collections.reverse(postfixStack);// Invert the suffix stack String firstValue, secondValue, currentValue;// The first value, secondValue, currentValue;// The first value, second value and arithmetic operator participating in the calculation while (!postfixStack.isEmpty()) {currentValue = postfixStack.pop();if (!isOperator(currentValue.charAt(0))) {// If it is not an operator, store it in the operand stack currentValue = currentValue.replace("~", "-");resultStack.push(currentValue);} else {// If it is an operator, take two values from the operand stack and participate in the operation together with the value secondValue = resultStack.pop();firstValue = resultStack.pop();// Change the negative number tag to a negative sign firstValue = firstValue.replace("~", "-");secondValue = secondValue.replace("~", "-");String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));resultStack.push(tempResult);}}return double.valueOf(resultStack.pop());}/** * The data preparation stage converts the expression into a suffix stack* * @param expression */private void prepare(String expression) {opStack.push(',');// The operator puts the comma in the bottom element of the stack, and this symbol has the lowest priority char[] arr = expression.toCharArray();int currentIndex = 0;// The current character position is int count = 0;// The length of the characters from the last arithmetic operator to this arithmetic operator is convenient or numerical char currentOp, peekOp;// The current operator and the top-stack operator for (int i = 0; i < arr.length; i++) {currentOp = arr[i];if (isOperator(currentOp)) {// If the current character is an operator if (count > 0) {postfixStack.push(new String(arr, currentIndex, count));// Take the number between two operators}peekOp = opStack.peek();if (currentOp == ')') {// When encountering an unbranch, remove the element in the operator stack to the suffix stack until the opening bracket is encountered (opStack.peek() != '(') {postfixStack.push(String.valueOf(opStack.pop()));}opStack.pop();} else {while (currentOp != '(' && peekOp != ',' && compare(currentOp, peekOp)) {postfixStack.push(String.valueOf(opStack.pop()));peekOp = opStack.peek();}opStack.push(currentOp);}count = 0;currentIndex = i + 1;} else {count++;}}if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {// If the last character is not a bracket or other operator, add it to the suffix stack postfixStack.push(new String(arr, currentIndex, count));}while (opStack.peek() != ',') {postfixStack.push(String.valueOf(opStack.pop()));// Add the remaining elements in the operator stack to the suffix stack}}/** * Determine whether it is an arithmetic symbol* * @param c * @return */private Boolean isOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';}/** * Use ASCII code-40 to mark the arithmetic symbol priority* * @param cur * @param peek * @return */public Boolean compare(char cur, char peek) {// If the peek priority is higher than cur, return true, the default peek priority is lower Boolean result = false; if (operatPriority[(peek) - 40] >= operatorPriority[(cur) - 40]) {result = true;}return result;}/** * Calculate according to the given arithmetic operator* * @param firstValue * @param secondValue * @param currentOp * @return */private String calculate(String firstValue, String secondValue, char currentOp) {String result = "";switch (currentOp) {case '+': result = String.valueOf(ArithHelper.add(firstValue, secondValue));break;case '-': result = String.valueOf(ArithHelper.sub(firstValue, secondValue));break;case '*': result = String.valueOf(ArithHelper.mul(firstValue, secondValue));break;case '/': result = String.valueOf(ArithHelper.div(firstValue, secondValue));break;}return result;}}The ArithHelper code is as follows:
public class ArithHelper {// Default division operation accuracy private static final int DEF_DIV_SCALE = 16;// This class cannot be instantiated private ArithHelper() {}/** * Provides accurate addition operations. * * @param v1 added* @param v2 add* @return The sum of the two parameters */public static double add(double v1, double v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(double.toString(v1));java.math.BigDecimal b2 = new java.math.BigDecimal(double.toString(v2));return b1.add(b2).doubleValue();}public static double add(String v1, String v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(v1);java.math.BigDecimal b2 = new java.math.BigDecimal(v2);return b1.add(b2).doubleValue();}/** * Provides accurate subtraction operations. * * @param v1 subtracted* @param v2 subtract* @return Difference between two parameters*/public static double sub(double v1, double v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(double.toString(v1));java.math.BigDecimal b2 = new java.math.BigDecimal(double.toString(v2));return b1.subtract(b2).doubleValue();}public static double sub(String v1, String v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(v1);java.math.BigDecimal b2 = new java.math.BigDecimal(v2);return b1.subtract(b2).doubleValue();}/** * Provides accurate multiplication operations. * * @param v1 * Multiplier* @param v2 * Multiplier* @return Product of two parameters*/public static double mul(double v1, double v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(double.toString(v1));java.math.BigDecimal b2 = new java.math.BigDecimal(double.toString(v2));return b1.multiply(b2).doubleValue();}public static double mul(String v1, String v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(v1);java.math.BigDecimal b2 = new java.math.BigDecimal(v2);return b1.multiply(b2).doubleValue();}/** * Provides (relatively) accurate division operation. When there is no division, it is accurate to 10 digits after the decimal point, and the subsequent numbers are rounded. * * @param v1 * Divider* @param v2 * Divider* @return Quotation of two parameters*/public static double div(double v1, double v2) {return div(v1, v2, DEF_DIV_SCALE);}public static double div(String v1, String v2) {java.math.BigDecimal b1 = new java.math.BigDecimal(v1);java.math.BigDecimal b2 = new java.math.BigDecimal(v2);return b1.divide(b2, DEF_DIV_SCALE, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();}/** * Provides (relatively) accurate division operation. When there is no end to complete the separation, the accuracy is specified by the scale parameter, and the subsequent numbers are rounded. * * @param v1 Divider* @param v2 Divider* @param scale means that it needs to be accurate to several digits after the decimal point. * @return quotient of two parameters*/public static double div(double v1, double v2, int scale) {if (scale < 0) {throw new IllegalArgumentException("The scale must be a positive integer or zero");}java.math.BigDecimal b1 = new java.math.BigDecimal(double.toString(v1));java.math.BigDecimal b2 = new java.math.BigDecimal(double.toString(v2));return b1.divide(b2, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();}/** * Provides accurate decimal rounding. * * @param v Counts that need to be rounded* @param scale How many digits are retained after the decimal point* @return The result after rounding*/public static double round(double v, int scale) {if (scale < 0) {throw new IllegalArgumentException("The scale must be a positive integer or zero");}java.math.BigDecimal b = new java.math.BigDecimal(double.toString(v));java.math.BigDecimal one = new java.math.BigDecimal("1");return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();}public static double round(String v, int scale) {if (scale < 0) {throw new IllegalArgumentException("The scale must be a positive integer or zero");}java.math.BigDecimal b = new java.math.BigDecimal(v);java.math.BigDecimal one = new java.math.BigDecimal("1");return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();}}When using it, call the conversion() method of the Calculator class and pass in the arithmetic expression parameter to return a value of type Double.
Example of usage:
public class MathTest {public static void main(String[] args) {String expression = "(0*1--3)-5/-4-(3*(-2.13))";double result = Calculator.conversion(expression);System.out.println(expression + " = " + result);System.out.println();}}Console output:
(0*1--3)-5/-4-(3*(-2.13)) = 10.64
Test screenshot:
Summarize
The above is all the detailed explanation of Java computational mathematical expression code, I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!