# 计算数学公式
/**
* 计算 表达式 如 (9+(11+12)/3^1)*1000
* 小数点精确 Round(2,10/3)
* (9+23.0/3^1)*1000/47.0
* (9+23/3^1)*1000/47.0
*/
public static double caculateExpression(String sExpression) {
double dValue = 0;
/*去掉空格*/
sExpression = org.springframework.util.StringUtils.trimAllWhitespace(sExpression);
if (sExpression.contains(")") && !sExpression.contains("(")) {
System.out.println("表达式 缺少 '(' 括号");
return 0;
}
if (sExpression.contains("(") && !sExpression.contains(")")) {
System.out.println("表达式 缺少 ')' 括号");
return 0;
}
String startTemp = "";
String sSubExpression = "";
for (int i = 0; i < sExpression.length(); i++) {
char c = sExpression.charAt(i);
if (bContainsIn(c, "(")) {
int flag = 0;
int roundCount = 0;
if(i-5>=0){
if(sExpression.substring(i-5,i).equals("Round")){
int dh =sExpression.indexOf(",",i);
startTemp = sExpression.substring(i-5,dh +1);
sSubExpression = sSubExpression.substring(0,sSubExpression.length()-5);
roundCount= Integer.parseInt(sExpression.substring(i+1,dh ));
if(i-5==0){
flag = 1;
}else {
flag = 2;
}
i=dh;
}
}
String ssexpression = "";
while ((i <= sExpression.length() - 2) && sExpression.charAt(++i) != ')') {
c = sExpression.charAt(i);
if (c == '(') {
if(i-5>=0){
if(sExpression.substring(i-5,i).equals("Round")){
ssexpression = ssexpression.substring(0,ssexpression.length()-5);
}
}
if (flag == 1) {
sSubExpression = startTemp + sSubExpression + ssexpression;
flag = 0;
} else if (flag == 2) {
sSubExpression = sSubExpression + startTemp + ssexpression;
flag = 0;
} else {
sSubExpression = sSubExpression + "(" + ssexpression;
}
ssexpression = "";
startTemp = "";
if(i-5>=0){
if(sExpression.substring(i-5,i).equals("Round")){
int dh = sExpression.indexOf(",",i);
startTemp = ssexpression + sExpression.substring(i-5,dh +1);
roundCount= Integer.parseInt(sExpression.substring(i+1,dh ));
flag = 2;
i= dh;
}
}
} else {
ssexpression += c;
}
}
if(flag!=0){
sSubExpression += String.valueOf(round(roundCount,dCaculateLevel1(ssexpression)));
}else {
sSubExpression += String.valueOf(dCaculateLevel1(ssexpression));
}
} else {
sSubExpression += c;
}
}
/* 递归调用 (9+23.0/3^1)*1000/47.0*/
if (bContainsIn(sSubExpression, "()")) {
dValue = caculateExpression(sSubExpression);
} else {
dValue = dCaculateLevel1(sSubExpression);
}
return dValue;
}
public static Double round(int pointLen, double value){
if(value>=value*-1){
value+=0.0000000001;
}else{
value-=0.0000000001;
}
if(pointLen>=0){
value = new BigDecimal(value).setScale(pointLen,BigDecimal.ROUND_HALF_UP).doubleValue();
}else{
int n = pointLen * -1 ;
for(int i=0;i<n;i++){
value = value / 10.0;
}
value = new BigDecimal(value).setScale(0,BigDecimal.ROUND_HALF_UP).doubleValue();
for(int i=0;i<n;i++){
value = value * 10.0;
}
}
return new Double(value);
}
/**
* 没有 括号 的 表达式 , 但可能有[ +, -, *, /, %, ^]
*/
public static double dCaculateLevel1(String sSubExpression) {
// 优先级 ^ 大于 /, *, % 大于 + - ; 处理 + , - 运算
// 9 + 12/3^2*3
// 10*9 - 9 + 12/9*3 - 10
String[] djia = sSubExpression.split("\\+");
double dValue = 0;
for (int i = 0; i < djia.length; i++) {
String[] split = djia[i].split("-");
double subValue = 0;
for (int j = 0; j < split.length; j++) {
String sLSubExpression = split[j];
if (split[j].endsWith("/") || split[j].endsWith("*") || split[j].endsWith("%")) {
for (int g = j + 1; g < split.length; g++) {
sLSubExpression += "-" + split[g];
if (!split[j].equals("/") || !split[j].equals("*") || !split[j].equals("%")) {
j = g;
break;
}
}
}
subValue = (j == 0) ? dLevel2(sLSubExpression) : ArithUtil.sub(subValue, dLevel2(sLSubExpression));
}
dValue = (i == 0) ? subValue : ArithUtil.add(dValue, subValue);
}
return dValue;
}
public static double dLevel2(String sSubExpression) {
// */% 12/24*2^2/12%2^2 处理 * 和 / 运算
double dValue = 0;
if (bContainsIn(sSubExpression, "+-*/%^") == false) {
dValue = dlevel4(sSubExpression);
} else {
String[] split1 = sSubExpression.split("\\*");
for (int i = 0; i < split1.length; i++) {
String[] split2 = split1[i].split("/");
for (int j = 0; j < split2.length; j++) {
if (i == 0 && j == 0) {
dValue = dLevel3(split2[j]);
} else {
dValue = (j == 0) ? ArithUtil.mul(dValue, dLevel3(split2[j])) : ((dLevel3(split2[j]) == 0) ? 0 : ArithUtil.div(dValue, dLevel3(split2[j])));
}
}
}
}
return dValue;
}
public static double dLevel3(String sSubExpression) {
// 8%2^2^2 处理 % 和 ^ 运算
double dValue = 0;
if (bContainsIn(sSubExpression, "+-*/%^") == false) {
dValue = dlevel4(sSubExpression);
} else {
String[] split = sSubExpression.split("%");
for (int i = 0; i < split.length; i++) {
String[] split2 = split[i].split("\\^");
double subValue = 0;
for (int j = 0; j < split2.length; j++) {
subValue = (j == 0) ? dlevel4(split2[j]) : dArith(subValue, dlevel4(split2[j]), '^');
}
dValue = (i == 0) ? subValue : dValue % subValue;
}
}
return dValue;
}
private static double dlevel4(String sSubExpression) {
if ("".equals(sSubExpression)) {
return 0;
}
return Double.parseDouble(sSubExpression);
}
public static boolean bContainsIn(char c, String src) {
boolean bResult = false;
for (int i = 0; i < src.length(); i++) {
char sc = src.charAt(i);
if (sc == c) {
bResult = true;
}
}
return bResult;
}
public static boolean bContainsIn(String src, String subString) {
boolean bResult = false;
for (int i = 0; i < subString.length(); i++) {
String s = subString.substring(i, i + 1);
if (src.contains(s)) {
bResult = true;
break;
}
}
return bResult;
}
public static double dArith(double dNumber1, double dNumber2, char cOperator) {
double dResult = 0;
if ('+' == cOperator) {
dResult = dNumber1 + dNumber2;
} else if ('-' == cOperator) {
dResult = dNumber1 - dNumber2;
} else if ('*' == cOperator) {
dResult = dNumber1 * dNumber2;
} else if ('/' == cOperator) {
dResult = dNumber1 / dNumber2;
} else if ('%' == cOperator) {
dResult = dNumber1 % dNumber2;
} else if ('^' == cOperator) {
if (dNumber2 == 0) {
dResult = 1;
} else {
dResult = 1;
for (int i = 0; i < dNumber2; i++) {
dResult = dResult * dNumber1;
}
}
}
return dResult;
}
public static boolean envalueRelationExpression(double dLeftValue, double dRightValue, String expressionRelation, int x) {
boolean bResult = false;
if (dLeftValue == 0 && dRightValue == 0) {
bResult = true;
return bResult;
}
if ("<".equals(expressionRelation)) {
if (dLeftValue < dRightValue) {
bResult = true;
}
} else if ("<=".equals(expressionRelation)) {
if (dLeftValue <= dRightValue) {
bResult = true;
}
} else if (">".equals(expressionRelation)) {
if (dLeftValue > dRightValue) {
bResult = true;
}
} else if (">=".equals(expressionRelation)) {
if (dLeftValue >= dRightValue) {
bResult = true;
}
} else if ("=".equals(expressionRelation)) {
/*因为计算涉及到四舍五入的问题,只要有小数点都四舍五入*/
return Math.round(dLeftValue) == Math.round(dRightValue);
} else if ("!=".equals(expressionRelation)) {
if (Math.abs(dLeftValue - dRightValue) > 0.001) {
bResult = true;
}
} else {
System.out.println("[method:envalueRelationExpression] 公式关系符出错");
}
return bResult;
}
/**
* 把实际值替换掉szLogicFormula中的项号,如 "{2}={42}/{5}" "B 3 56 60 20",返回"3=60/20"
*/
public static String replaceItemWithValue(String sExpression, String sLineData, int count) {
String ks = "";
for (int i = 0; i < sExpression.length(); i++) {
char c = sExpression.charAt(i);
if ('{' == c) {
String szItemNumber = "";
while (i <= sExpression.length() - 2 && sExpression.charAt(++i) != '}') {
szItemNumber += sExpression.charAt(i);
}
int nItemNumber = Integer.parseInt(szItemNumber) + count;
String szIterValue = RPTField.getField(sLineData, nItemNumber);
ks += szIterValue;
} else {
ks += c;
}
}
return ks;
}
/**
* 检查公式里小数位数最多的数有几位
*/
public static int maxFractionInExpression(String sLineData) {
int max = 0;
for (int i = 0; i < sLineData.length(); i++) {
char c = sLineData.charAt(i);
if ('.' == c) {
i++;
int k = 0;
while (i < sLineData.length() - 1 && sLineData.charAt(i) >= '0' && sLineData.charAt(i) <= '9') {
k++;
i++;
}
if (max < k) {
max = k;
}
}
}
return max;
}