`
weixuanfeng
  • 浏览: 7623 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类

看看,输入19²为什么得不到预期结果,9^3就可以,这是计算器的代码,别改乱了,关键处理²次方

阅读更多
/*
* 文 件 名:  Calc.java
* 描    述:  <描述>
* 修 改 人:  韦旋枫 CEA00260
* 修改时间:  2011-5-12
* 修改内容:  <修改内容>
*/
package com.xuanfeng.test;

import java.text.DecimalFormat;
import java.util.StringTokenizer;

/**
* <一句话功能简述> <功能详细描述>
*
* @author 姓名 工号
* @version [版本号, 2011-5-12]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class Calc
{
    static Calc calc = new Calc();
   
    public static void main(String[] args)
    {
//        calc.process("9^3+9-sin60");
         calc.process("19²");
    }
   
    /*
     * 整个计算核心,只要将表达式的整个字符串传入calc().process()就可以实行计算了 算法包括以下几部分: 1、计算部分 process(String str) 当然,这是建立在查错无错误的情况下 2、数据格式化
     * FP(double n) 使数据有相当的精确度 3、阶乘算法 N(double n) 计算n!,将结果返回 4、错误提示 showError(int code ,String str) 将错误返回
     */
    public Calc()
    {
       
    }
   
    // 保存原来的算式样子,为了输出时好看,因计算时,算式样子被改变
    public String str_old;
   
    // 控制DRG按键,true为角度,false为弧度
    public boolean drg_flag = true;
   
    // π 3.14
    public double pi = Math.PI;
   
    final int MAXLEN = 500;
   
    /*
     * 计算表达式 从左向右扫描,数字入number栈,运算符入operator栈 +-基本优先级为1,×÷基本优先级为2,log ln sin cos tan n!基本优先级为3,√^基本优先级为4
     * 括号内层运算符比外层同级运算符优先级高4 当前运算符优先级高于栈顶压栈,低于栈顶弹出一个运算符与两个数进行运算 重复直到当前运算符大于栈顶 扫描完后对剩下的运算符与数字依次计算
     */
    public void process(String str)
    {
        // weightPlus为同一()下的基本优先级,weightTemp临时记录优先级的变化
        int weightPlus = 0;
       
        // topOp为weight[],operator[]的计数器;
        int topOp = 0;
       
        // topNum为number[]的计数器
        int topNum = 0;
       
        // flag为正负数的计数器,1为正数,-1为负数
        int flag = 1;
       
        int weightTemp = 0;
       
        // 保存operator栈中运算符的优先级,以topOp计数
        int weight[];
       
        // 保存数字,以topNum计数
        double number[];
       
        // operator[]保存运算符,以topOp计数
        char ch, ch_gai, operator[];
       
        // 记录数字,str以+-×÷()sctgl!√^分段,+-×÷()sctgl!√^字符之间的字符串即为数字
        String num;
       
        weight = new int[MAXLEN];
       
        number = new double[MAXLEN];
       
        operator = new char[MAXLEN];
       
        // String expression1 = str;
       
        StringTokenizer expToken = new StringTokenizer(str, "+-×÷()sctgl!√^²³");
       
        int i = 0;
       
        while (i < str.length())
        {
            ch = str.charAt(i);
           
            if (i == 0)
            {
                if (ch == '-')
                    flag = -1;
            }
            else if (str.charAt(i - 1) == '(' && ch == '-')
                flag = -1;
           
            if (ch <= '9' && ch >= '0' || ch == '.' || ch == 'E')
            {
                num = expToken.nextToken();
                ch_gai = ch;
               
                while (i < str.length() && (ch_gai <= '9' && ch_gai >= '0' || ch_gai == '.' || ch_gai == 'E'))
                {
                    ch_gai = str.charAt(i++);
                }
               
                if (i >= str.length())
                {
                    i -= 1;
                }
                else
                {
                    i -= 2;
                }
               
                if (num.compareTo(".") == 0)
                {
                    number[topNum++] = 0;
                }
                else
                {
                    number[topNum++] = Double.parseDouble(num) * flag;
                    flag = 1;
                }
            }
            if (ch == '(')
            {
                weightPlus += 4;
            }
            if (ch == ')')
            {
                weightPlus -= 4;
            }
           
            if (ch == '-' && flag == 1 || ch == '+' || ch == '×' || ch == '÷' || ch == 's' || ch == 'c' || ch == 't'
                || ch == 'g' || ch == 'l' || ch == '!' || ch == '√' || ch == '^' || ch == '²' || ch == '³')
            {
                switch (ch)
                {
                    case '+':
                    case '-':
                        weightTemp = 1 + weightPlus;
                        break;
                    case '×':
                    case '÷':
                        weightTemp = 2 + weightPlus;
                        break;
                    case 's':
                    case 'c':
                    case 't':
                    case 'g':
                    case 'l':
                    case '!':
                        weightTemp = 3 + weightPlus;
                        break;
                    // case '^':
                    // case '√':
                    default:
                        weightTemp = 4 + weightPlus;
                        break;
                }
               
                if (topOp == 0 || weight[topOp - 1] < weightTemp)
                {
                    weight[topOp] = weightTemp;
                    operator[topOp] = ch;
                    topOp++;
                }
                else
                {
                    while (topOp > 0 && weight[topOp - 1] >= weightTemp)
                    {
                        switch (operator[topOp - 1])
                        {
                            case '+':
                                number[topNum - 2] += number[topNum - 1];
                                break;
                           
                            case '-':
                                number[topNum - 2] -= number[topNum - 1];
                               
                            case '×':
                                number[topNum - 2] *= number[topNum - 1];
                                break;
                           
                            case '÷':
                                if (number[topNum - 1] == 0)
                                {
                                    showError(1, str_old);
                                    return;
                                }
                                number[topNum - 2] /= number[topNum - 1];
                                break;
                           
                            case '√':
                                if (number[topNum - 1] == 0 || (number[topNum - 2] < 0 && number[topNum - 1] % 2 == 0))
                                {
                                    showError(2, str_old);
                                    return;
                                }
                                number[topNum - 2] = Math.pow(number[topNum - 2], 1 / number[topNum - 1]);
                                break;
                           
                            case '^':
                                number[topNum - 2] = Math.pow(number[topNum - 2], number[topNum - 1]);
                                break;
                           
                            case '²':
                                number[topNum] = Math.pow(number[topNum], 2);
                                break;
                           
                            case '³':
                                number[topNum] = Math.pow(number[topNum], 3);
                                break;
                           
                            case 's':
                                if (drg_flag == true)
                                {
                                    number[topNum - 1] = Math.sin((number[topNum - 1] / 180) * pi);
                                }
                                else
                                {
                                    number[topNum - 1] = Math.sin(number[topNum - 1]);
                                }
                                topNum++;
                                break;
                           
                            case 'c':
                                if (drg_flag == true)
                                {
                                    number[topNum - 1] = Math.cos((number[topNum - 1] / 180) * pi);
                                }
                                else
                                {
                                    number[topNum - 1] = Math.cos(number[topNum - 1]);
                                }
                                topNum++;
                                break;
                           
                            case 't':
                                if (drg_flag == true)
                                {
                                    if ((Math.abs(number[topNum - 1]) / 90) % 2 == 1)
                                    {
                                        showError(2, str_old);
                                        return;
                                    }
                                    number[topNum - 1] = Math.tan((number[topNum - 1] / 180) * pi);
                                }
                                else
                                {
                                    if ((Math.abs(number[topNum - 1]) / (pi / 2)) % 2 == 1)
                                    {
                                        showError(2, str_old);
                                        return;
                                    }
                                   
                                    number[topNum - 1] = Math.tan(number[topNum - 1]);
                                }
                                topNum++;
                                break;
                           
                            case 'g':
                                if (number[topNum - 1] <= 0)
                                {
                                    showError(2, str_old);
                                    return;
                                }
                                number[topNum - 1] = Math.log10(number[topNum - 1]);
                                topNum++;
                                break;
                           
                            case 'l':
                                if (number[topNum - 1] <= 0)
                                {
                                    showError(2, str_old);
                                    return;
                                }
                                number[topNum - 1] = Math.log(number[topNum - 1]);
                                topNum++;
                                break;
                           
                            case '!':
                                if (number[topNum - 1] > 170)
                                {
                                    showError(3, str_old);
                                    return;
                                }
                                else if (number[topNum - 1] < 0)
                                {
                                    showError(2, str_old);
                                    return;
                                }
                                number[topNum - 1] = n(number[topNum - 1]);
                                topNum++;
                                break;
                        }
                        switch (operator[topOp])
                        {
                           
                            case '²':
                                number[topNum] = Math.pow(number[topNum], 2);
                                break;
                           
                            case '³':
                                number[topNum] = Math.pow(number[topNum], 3);
                                break;
                        }
                       
                        topNum--;
                        topOp--;
                    }
                    weight[topOp] = weightTemp;
                    operator[topOp] = ch;
                    topOp++;
                }
            }
            i++;
        }
       
        while (topOp > 0)
        {
            switch (operator[topOp - 1])
            {
                case '+':
                    number[topNum - 2] += number[topNum - 1];
                    break;
               
                case '-':
                    number[topNum - 2] -= number[topNum - 1];
                    break;
               
                case '×':
                    number[topNum - 2] *= number[topNum - 1];
                    break;
               
                case '÷':
                    if (number[topNum - 1] == 0)
                    {
                        showError(1, str_old);
                        return;
                    }
                    number[topNum - 2] /= number[topNum - 1];
                    break;
               
                case '√':
                    if (number[topNum - 1] == 0 || (number[topNum - 2] < 0 && number[topNum - 1] % 2 == 0))
                    {
                        showError(2, str_old);
                        return;
                    }
                    number[topNum - 2] = Math.pow(number[topNum - 2], 1 / number[topNum - 1]);
                    break;
               
                case '^':
                    number[topNum - 2] = Math.pow(number[topNum - 2], number[topNum - 1]);
                    break;
               
               
                case 's':
                    if (drg_flag == true)
                    {
                        number[topNum - 1] = Math.sin((number[topNum - 1] / 180) * pi);
                    }
                    else
                    {
                        number[topNum - 1] = Math.sin(number[topNum - 1]);
                    }
                    topNum++;
                    break;
               
                case 'c':
                    if (drg_flag == true)
                    {
                        number[topNum - 1] = Math.cos((number[topNum - 1] / 180) * pi);
                    }
                    else
                    {
                        number[topNum - 1] = Math.cos(number[topNum - 1]);
                    }
                    topNum++;
                    break;
               
                case 't':
                    if (drg_flag == true)
                    {
                        if ((Math.abs(number[topNum - 1]) / 90) % 2 == 1)
                        {
                            showError(2, str_old);
                            return;
                        }
                        number[topNum - 1] = Math.tan((number[topNum - 1] / 180) * pi);
                    }
                    else
                    {
                        if ((Math.abs(number[topNum - 1]) / (pi / 2)) % 2 == 1)
                        {
                            showError(2, str_old);
                            return;
                        }
                        number[topNum - 1] = Math.tan(number[topNum - 1]);
                    }
                    topNum++;
                    break;
               
                case 'g':
                    if (number[topNum - 1] <= 0)
                    {
                        showError(2, str_old);
                        return;
                    }
                    number[topNum - 1] = Math.log10(number[topNum - 1]);
                    topNum++;
                    break;
               
                case 'l':
                    if (number[topNum - 1] <= 0)
                    {
                        showError(2, str_old);
                        return;
                    }
                    number[topNum - 1] = Math.log(number[topNum - 1]);
                    topNum++;
                    break;
               
                case '!':
                    if (number[topNum - 1] > 170)
                    {
                        showError(3, str_old);
                        return;
                    }
                    else if (number[topNum - 1] < 0)
                    {
                        showError(2, str_old);
                        return;
                    }
                    number[topNum - 1] = n(number[topNum - 1]);
                    topNum++;
                    break;
            }

            switch (operator[topOp])
            {
               
                case '²':
                    number[topNum] = Math.pow(number[topNum], 2);
                    break;
               
                case '³':
                    number[topNum] = Math.pow(number[topNum], 3);
                    break;
            }
            topNum--;
            topOp--;
        }
       
        if (number[0] > 7.3E306)
        {
            showError(3, str_old);
            // input.setText("\""+str_old+"\": 太大了,我不行了");
            return;
        }
       
        System.out.println(String.valueOf(fp(number[0])));
       
        // input.setText(String.valueOf(fp(number[0]))); // 输出最终结果
       
        // tip.setText("计算完毕,要继续请按归零键 C");
       
        // mem.setText(str_old + "=" + String.valueOf(fp(number[0])));
       
    }
   
    /*
     * FP = floating point 控制小数位数,达到精度 否则会出现 0.6-0.2=0.39999999999999997的情况,用FP即可解决,使得数为0.4 本格式精度为15位
     */
    public double fp(double n)
    {
        DecimalFormat format = new DecimalFormat("0.#############");
       
        return Double.parseDouble(format.format(n));
    }
   
    /*
     * 阶乘算法
     */
    public double n(double n)
    {
        int i = 0;
       
        double sum = 1;
       
        for (i = 1; i <= n; i++)
        {
            sum = sum * i;
        }
        return sum;
    }
   
    /*
     * 错误提示,按了"="之后,若计算式在process()过程中,出现错误,则进行提示
     */
    public void showError(int code, String str)
    {
        String message = "";
       
        switch (code)
        {
            case 1:
                message = "零不能作除数";
                break;
           
            case 2:
                message = "函数格式错误";
                break;
           
            case 3:
                message = "值太大了,我不行了";
        }
       
        System.out.println("\"" + str + "\"" + ": " + message);
        // input.setText("\"" + str + "\"" + ": " + message);
       
        // tip.setText(message + "\n" + "计算完毕,要继续请按归零键 C");
    }
   
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics