看看,输入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");
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值