批处理之家's Archiver

happy886rr 发表于 2017-8-6 23:28

JAVA第三方计算工具: jcalc

[i=s] 本帖最后由 happy886rr 于 2017-8-7 11:07 编辑 [/i]

[1.0.0.6]版,修复数组边界漏洞,修复随机函数算法。
跨平台JAVA第三方计算工具: jcalc.jar,使用增强版revpolish核心打造的。从 手机端 到 桌面端、服务器端 全覆盖运行。(所有图片一律为外链,jar包仅10kb,请下载附件[attach]10806[/attach]。)
[quote]
兼容性   :java 1.6、java7、java8
跨平台性:完全做到一次编译,处处运行。可在各类安卓手机上直接运行,windows、linux、unix、mac、树莓派、各类微型智能设备,只要具备jre环境均可运行,不具备也可使用API转化技术运行。针对IOS设备可使用j2oc转化技术运行。
WINDOWS下运行图
[img]http://i1.bvimg.com/1949/d9085dcdedc1ee48.png[/img]

linux下运行图

手机端运行请使用 ej 脚本运行[url]http://www.bathome.net/thread-44950-1-1.html[/url],更为便捷。
安卓手机下运行图
[img]http://i1.bvimg.com/1949/b45ad305cf7f35e8.png[/img]
[/quote]

原创代码:[code]
package com.android.jcalc;


/**Main主类
* @author Happy from BatHome
* @date Thu Aug 06 2017 20:11:16 GMT+0800
* @description jcalc.jar
*/
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];


        /**阶乘函数
         * @param n
         * @return
         */
        private static long fact(long n)
        {
                return (n<2) ?1 :n*(fact(n-1));
        }
       
        /**计算器核心
         * @param expression
         */
        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)
                                {
                                        //90度没有正切值
                                        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)
                                {
                                        //小于2的随机数为0~1之间的小数
                                        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);
                }

                //返回计算结果
                //return STACK3[indexS3];

                //打印中缀式
                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;
        }


        /**主函数入口
         * @param args
         */
        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;
        }
}
[/code]

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.