| package com.android.jcalc; |
| |
| |
| |
| |
| |
| |
| |
| public class Main |
| { |
| |
| private static final String HELP_INFORMATION = |
| "" |
| + "JCALC.JAR - JAVA CONSOLE CALCULATE TOOL, COPYRIGHT@2017~2019 BY HAPPY\n" |
| + "-----------------------------------------------------------------------\n" |
| + "Usage instructions:\n" |
| + " java -jar jcalc.jar [expression]\n" |
| + " java -Xms128m -Xmx1024m -jar jcalc.jar ...\n" |
| + "-----------------------------------------------------------------------\n" |
| + "General options:\n" |
| + " --help, -h Show help information\n\n" |
| + "Available math function:\n" |
| + " pi=3.1415926535897932, e=2.7182818284590452\n" |
| + " rand, round, int, ceil, floor, abs, sqrt, lg, ln, exp, cbrt\n" |
| + " torad, sin, cos, tan, arcsin, arccos, arctan\n" |
| + " sinh, cosh, tanh, arcsinh, arccosh, arctanh\n\n" |
| + "Official website:\n" |
| + " http://www.bathome.net/thread-18688-1-1.html\n" |
| + "-----------------------------------------------------------------------\n" |
| + "AT LEAST JRE1.6, VERSION: 1.0.0.6\n"; |
| |
| |
| private static final String KEY_WORDS[]= {"e", "pi", "sqrt", "lg", "ln", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "torad", "abs", "round", "floor", "ceil", "exp", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", "int", "cbrt", "rand", null}; |
| |
| |
| private static final int STACK_SIZE = 1024; |
| private static char[] STACK1= new char[STACK_SIZE]; |
| private static char[] STACK2= new char[STACK_SIZE]; |
| private static double[] STACK3= new double[STACK_SIZE]; |
| |
| |
| |
| |
| |
| |
| private static long fact(long n) |
| { |
| return (n<2) ?1 :n*(fact(n-1)); |
| } |
| |
| |
| |
| |
| private static double JCalcCore(String expression) |
| { |
| char[] parseArray = expression.toCharArray(); |
| int parseArrayLen = parseArray.length; |
| |
| char[] tmpKeyCharArray; |
| int tmpKeyCharArrayLen; |
| |
| int indexS1=0, indexS2=0, indexS3=0, brackets=0, indexKey, op, cp, kp; |
| double di, ni; |
| |
| |
| STACK3[0]=0; |
| op = 0; |
| |
| |
| while(op < parseArrayLen) |
| { |
| switch(parseArray[op]) |
| { |
| case ' ' : |
| case '\t': |
| case '\r': |
| case '\n': |
| |
| op++; |
| continue; |
| |
| case '(': |
| brackets++; |
| STACK1[++indexS1]=parseArray[op]; |
| if(parseArray[op+1]=='-' || parseArray[op+1]=='+') |
| { |
| STACK2[indexS2++]='0'; |
| STACK2[indexS2++]=' '; |
| } |
| break; |
| |
| case ')': |
| |
| if(brackets ==0) |
| { |
| System.out.println("The brackets or ')' are not need"); |
| System.exit(1); |
| } |
| brackets--; |
| while(STACK1[indexS1] != '(') |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| |
| indexS1--; |
| break; |
| |
| case '+': |
| case '-': |
| while( (indexS1 != 0) && (STACK1[indexS1] != '(') ) |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| STACK1[++indexS1] = parseArray[op]; |
| break; |
| |
| case '^': |
| |
| while('A'<=STACK1[indexS1] && STACK1[indexS1]<='Z') |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| STACK1[++indexS1] = parseArray[op]; |
| break; |
| |
| case '!': |
| |
| STACK2[indexS2++] = parseArray[op]; |
| break; |
| |
| case '%': |
| case '*': |
| case '/': |
| while( |
| ( |
| ('A' <= STACK1[indexS1]) && |
| (STACK1[indexS1] <= 'Z') |
| ) || |
| STACK1[indexS1]=='%' || |
| STACK1[indexS1]=='*' || |
| STACK1[indexS1]=='/' || |
| STACK1[indexS1]=='^' |
| ) |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| STACK1[++indexS1] = parseArray[op]; |
| break; |
| |
| default : |
| if('a'<=parseArray[op] && parseArray[op]<='z') |
| { |
| |
| indexKey = 0; |
| while(KEY_WORDS[indexKey] != null) |
| { |
| cp=op; |
| kp=0; |
| |
| tmpKeyCharArray = KEY_WORDS[indexKey].toCharArray(); |
| tmpKeyCharArrayLen = tmpKeyCharArray.length; |
| |
| |
| while( |
| (kp < tmpKeyCharArrayLen) && |
| (cp < parseArrayLen) && |
| (parseArray[cp] == tmpKeyCharArray[kp]) |
| ){ |
| cp++; |
| kp++; |
| } |
| |
| if( |
| (kp == tmpKeyCharArrayLen) && |
| ( |
| (tmpKeyCharArrayLen == parseArrayLen) || |
| (parseArray[cp]<'a' || parseArray[cp]>'z') |
| ) |
| ) |
| { |
| op=cp; |
| break; |
| } |
| indexKey++; |
| } |
| |
| if(KEY_WORDS[indexKey] != null) |
| { |
| STACK2[indexS2++]='.'; |
| STACK2[indexS2++]=' '; |
| |
| while('A'<=STACK1[indexS1] && STACK1[indexS1]<='Z') |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| STACK1[++indexS1] = (char)(indexKey+65); |
| continue; |
| } |
| else |
| { |
| |
| System.out.println("Unrecognized math function\n"); |
| System.exit(1); |
| } |
| |
| } |
| else if(('0'<=parseArray[op] && parseArray[op]<='9') || (parseArray[op]=='.')) |
| { |
| |
| while( |
| (op < parseArrayLen) && |
| ( |
| ('0'<=parseArray[op] && parseArray[op]<='9') || |
| (parseArray[op]=='.') |
| ) |
| ){ |
| STACK2[indexS2++] = parseArray[op++]; |
| } |
| |
| if( |
| (op < parseArrayLen) && |
| ('a'<=parseArray[op] && parseArray[op]<='z') |
| ){ |
| |
| System.out.println("Missing required operator\n"); |
| System.exit(1); |
| } |
| op--; |
| STACK2[indexS2++] = ' '; |
| } |
| else |
| { |
| |
| System.out.println("Unrecognized operator\n"); |
| System.exit(1); |
| } |
| break; |
| } |
| op++; |
| } |
| |
| |
| if(brackets !=0) |
| { |
| System.out.println("The brackets '(' are not closed\n"); |
| System.exit(1); |
| } |
| |
| |
| while(indexS1 !=0) |
| { |
| STACK2[indexS2++] = STACK1[indexS1--]; |
| } |
| STACK2[indexS2] = ' '; |
| |
| |
| op=0; |
| while(STACK2[op] != ' ') |
| { |
| switch(STACK2[op]) |
| { |
| case 'A': |
| STACK3[indexS3] = Math.E; |
| break; |
| case 'B': |
| STACK3[indexS3] = Math.PI; |
| break; |
| case 'C': |
| if(STACK3[indexS3] <0) |
| { |
| |
| System.out.println("Negative numbers have no square root\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3 - 1] = Math.sqrt(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'D': |
| if(STACK3[indexS3] <0) |
| { |
| |
| System.out.println("Negative numbers are not logarithmic\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3 - 1] = Math.log10(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'E': |
| if(STACK3[indexS3] <0) |
| { |
| |
| System.out.println("Negative numbers have no natural logarithms\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3 - 1] = Math.log(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'F': |
| STACK3[indexS3 - 1] = Math.sin(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'G': |
| STACK3[indexS3 - 1] = Math.cos(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'H': |
| if(STACK3[indexS3] == Math.PI/2) |
| { |
| |
| System.out.println("The pi/2 has no tangent\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3 - 1] = Math.tan(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'I': |
| STACK3[indexS3 - 1] = Math.asin(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'J': |
| STACK3[indexS3 - 1] = Math.acos(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'K': |
| STACK3[indexS3 - 1] = Math.atan(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'L': |
| STACK3[indexS3 - 1] = Math.toRadians(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'M': |
| STACK3[indexS3 - 1] = Math.abs(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'N': |
| STACK3[indexS3 - 1] = Math.round(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'O': |
| STACK3[indexS3 - 1] = Math.floor(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'P': |
| STACK3[indexS3 - 1] = Math.ceil(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'Q': |
| STACK3[indexS3 - 1] = Math.exp(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'R': |
| STACK3[indexS3 - 1] = Math.sinh(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'S': |
| STACK3[indexS3 - 1] = Math.cosh(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'T': |
| STACK3[indexS3 - 1] = Math.tanh(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'U': |
| STACK3[indexS3 - 1] = Math.log(STACK3[indexS3]+Math.sqrt(STACK3[indexS3]*STACK3[indexS3]+1)); |
| indexS3--; |
| break; |
| case 'V': |
| STACK3[indexS3 - 1] = Math.log(STACK3[indexS3]+Math.sqrt(STACK3[indexS3]*STACK3[indexS3]-1)); |
| indexS3--; |
| break; |
| case 'W': |
| STACK3[indexS3 - 1] = Math.log((1+STACK3[indexS3])/(1-STACK3[indexS3]))/2; |
| indexS3--; |
| break; |
| case 'X': |
| STACK3[indexS3 - 1] = (int)(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'Y': |
| STACK3[indexS3 - 1] = Math.cbrt(STACK3[indexS3]); |
| indexS3--; |
| break; |
| case 'Z': |
| |
| if(STACK3[indexS3] <0) |
| { |
| |
| System.out.println("A negative number can not be used as a random upper bound"); |
| System.exit(1); |
| } |
| else if(STACK3[indexS3] <2) |
| { |
| |
| STACK3[indexS3 - 1] = Math.random(); |
| } |
| else |
| { |
| STACK3[indexS3 - 1] = (int)(Math.random() * (STACK3[indexS3])); |
| } |
| indexS3--; |
| break; |
| case '+': |
| STACK3[indexS3 - 1] += STACK3[indexS3]; |
| indexS3--; |
| break; |
| case '-': |
| STACK3[indexS3 - 1] -= STACK3[indexS3]; |
| indexS3--; |
| break; |
| case '*': |
| STACK3[indexS3 - 1] *= STACK3[indexS3]; |
| indexS3--; |
| break; |
| case '%': |
| case '/': |
| if(STACK3[indexS3] != 0) |
| { |
| if(STACK2[op] == '%') |
| { |
| |
| STACK3[indexS3 - 1]=(int)STACK3[indexS3 - 1] % (int)STACK3[indexS3]; |
| } |
| else |
| { |
| STACK3[indexS3 - 1] /= STACK3[indexS3]; |
| } |
| |
| } |
| else |
| { |
| |
| System.out.println("Divisor is zero error\n"); |
| System.exit(1); |
| } |
| indexS3--; |
| break; |
| case '^': |
| if(STACK3[indexS3 - 1]==0 && STACK3[indexS3]<0) |
| { |
| |
| System.out.println("Function pow's divisor is zero error\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3 - 1] = Math.pow(STACK3[indexS3 - 1], STACK3[indexS3]); |
| indexS3--; |
| break; |
| case '!': |
| if(STACK3[indexS3] <0) |
| { |
| |
| System.out.println("Negative numbers have no factorial\n"); |
| System.exit(1); |
| } |
| STACK3[indexS3]=fact((long)(STACK3[indexS3])); |
| break; |
| default : |
| |
| di=0; |
| ni=1; |
| while('0'<=STACK2[op] && STACK2[op]<='9') |
| { |
| di=10*di+(STACK2[op])-'0'; |
| op++; |
| } |
| if(STACK2[op] == '.') |
| { |
| op++; |
| while('0'<=STACK2[op] && STACK2[op]<='9') |
| { |
| di=10*di+(STACK2[op])-'0'; |
| op++; |
| ni *= 10; |
| } |
| } |
| STACK3[++indexS3] = di/ni; |
| break; |
| } |
| op++; |
| } |
| |
| |
| if( Double.isInfinite((float)STACK3[indexS3]) || Double.isNaN((float)STACK3[indexS3]) ) |
| { |
| System.out.println("Overflow or illegal operation is calculated"); |
| System.exit(1); |
| } |
| |
| |
| |
| |
| |
| System.out.printf("OriginalExp: %s\n", expression); |
| |
| |
| System.out.printf("Revpolish: "); |
| |
| op = 0; |
| while(op != indexS2) |
| { |
| if(STACK2[op]=='.' && STACK2[op+1]==' ') |
| { |
| op++; |
| |
| } |
| else if('A'<=STACK2[op] && STACK2[op]<='Z') |
| { |
| System.out.printf("%s ", KEY_WORDS[STACK2[op]-65]); |
| |
| } |
| else |
| { |
| System.out.printf("%c", STACK2[op]); |
| |
| if( |
| STACK2[op] == '+' || |
| STACK2[op] == '-' || |
| STACK2[op] == '*' || |
| STACK2[op] == '/' || |
| STACK2[op] == '%' || |
| STACK2[op] == '^' || |
| STACK2[op] == '!' |
| ) |
| { |
| System.out.printf(" "); |
| } |
| } |
| op++; |
| } |
| System.out.printf("%c", '\n'); |
| |
| |
| System.out.printf("Result: %.12f\n", STACK3[indexS3]); |
| return 0.0f; |
| } |
| |
| |
| |
| |
| |
| public static void main(String[] args) |
| { |
| |
| if (args.length != 1 || args[0].equals("-h") || args[0].equals("--help")) |
| { |
| System.out.println(HELP_INFORMATION); |
| return; |
| } |
| |
| |
| JCalcCore(args[0]); |
| return; |
| } |
| }COPY |