/// <summary> /// 分段函数 /// </summary> private static CalNum subfuns(StringBuilder funExpr, List<CalNum> numList) { CalNum result = null; if (funExpr.ToString().IndexOf("subfuns(") == -1) { MakeException("分段函数语法不正确"); } if (funExpr[funExpr.Length - 1] != ')') { MakeException("分段函数语法不正确"); } funExpr.Replace("subfuns(", ""); funExpr.Remove(funExpr.Length - 1, 1); CalNum num = numList[0];//仅支持对第一个参数分段 bool isBeyond = true;//是否越界 string[] funs = funExpr.ToString().Split(','); if (funs.Length % 3 != 0) { MakeException("subfuns的参数个数不正确,必须三个为一组"); } for (int i = 0; i < funs.Length; i += 3)//每三个一组:左边界、右边界、对应表达式 { double leftBoundary = double.MinValue;//左边界 double rightBoundary = double.MaxValue;//右边界 bool leftHollow = false;//左边界是否空心,默认是实心 bool rightHollow = false;//右边界是否空心,默认是实心 bool isIn = false;//参数是否在该范围内,默认false if (funs[i].IndexOf(">") != -1)//左边界空心 { leftHollow = true; leftBoundary = double.Parse(funs[i].Substring(1)); } else { leftBoundary = double.Parse(funs[i]); } if (funs[i + 1].IndexOf("<") != -1)//右边界空心 { rightHollow = true; rightBoundary = double.Parse(funs[i + 1].Substring(1)); } else { rightBoundary = double.Parse(funs[i + 1]); } #region 判断参数是否在当前范围内 if (leftHollow == true)//左边界空心 { if (rightHollow == true)//右边界空心 { if (num.DoubleValue > leftBoundary && num.DoubleValue < rightBoundary) { isIn = true; } } else//右边界实心 { if (num.DoubleValue > leftBoundary && num.DoubleValue <= rightBoundary) { isIn = true; } } } else//左边界实心 { if (rightHollow == true)//右边界空心 { if (num.DoubleValue >= leftBoundary && num.DoubleValue < rightBoundary) { isIn = true; } } else//右边界实心 { if (num.DoubleValue >= leftBoundary && num.DoubleValue <= rightBoundary) { isIn = true; } } } #endregion if (isIn)//如果参数在当前范围内 { isBeyond = false;//没有越界 //计算 bool bl1; string str = Common.DeleteAnnotate(funs[i + 2], out bl1);//删除注释 CalValList valList = new CalValList(str); CalResult calResult = valList.Calculate(); if (calResult.numList.Count == 1)//一个计算结果 { result = calResult.numList[0]; } else//多个计算结果 { result = new CalNum(calResult.GeneralResultToShow.Trim()); } //跳出循环 break; } } if (isBeyond) { MakeException("输入的参数超出定义的范围"); } return result; }
/// <summary> /// 存储变量 /// </summary> private void memoryVars() { string[] variables = Properties.Settings.Default.strVariables.Split('|'); //进入该函数说明'='存在,下面两条语句不会出错 string leftValue = txtExp.Text.Split('=')[0]; string rightValue = txtExp.Text.Split('=')[1]; //等号右边计算结果 string rightResult = ""; //支持存储15个变量 int maxVarLength = 30; #region 赋值语句不合法的情况 //确保只有一个'=' if (txtExp.Text.Split('=').Length > 2) { txtResult.Text = "变量赋值语句不合法"; return; } //左右值存在 if (txtExp.Text.Split('=')[0].Trim() == "" || txtExp.Text.Split('=')[1].Trim() == "") { txtResult.Text = "变量赋值语句不合法"; return; } //变量名称不合法的情况 //变量名称中不能存在单引号 if (leftValue.IndexOf("'") != -1) { txtResult.Text = "变量赋值语句不合法"; return; } double d; //变量名称不能全为数字 if (double.TryParse(leftValue, out d) || double.TryParse(leftValue.Substring(0, 1), out d)) { txtResult.Text = "变量名称不合法"; return; } //单引号必须成对出现,且最多只能有一对 if (rightValue.Split('\'').Length != 1 && rightValue.Split('\'').Length != 3) { txtResult.Text = "变量赋值语句不合法"; return; } #endregion //计算等号右边 if (rightValue[0] == '\'' && rightValue[rightValue.Length - 1] == '\'') { rightResult = rightValue.Replace("'", ""); } else { CalValList valList = new CalValList(rightValue); rightResult = valList.Calculate().GeneralResultToShow.Replace(" ", ""); txtExp.Text = leftValue + "=" + valList.nomalStringExpression; } if (variables.Length == 1)//特殊情况 { Properties.Settings.Default.strVariables = leftValue + "|" + rightResult; Properties.Settings.Default.Save(); txtResult.Text = "变量'" + leftValue + "'已赋值为'" + rightResult + "'"; } else { #region 查找是否存在同名变量或同名运算符或常数 bool homonymyOpe = false; bool varExists = false; int existsVarPos = -1;//同名变量位置 //是否存在同名变量 for (int i = 0; i < variables.Length; i += 2) { //找到同名变量 if (variables[i] == leftValue) { existsVarPos = i; varExists = true; break; } } //是否存在同名运算符 CalOpeList opeList = new CalOpeList(); for (int i = 0; i < opeList.count; i++) { //找到同名运算符 if (opeList.opeList[i].tag == leftValue) { homonymyOpe = true; break; } } #endregion #region 存在同名变量,替换变量 if (varExists) { if (MessageBox.Show("变量'" + leftValue + "'已存在,且它的值为'" + variables[existsVarPos + 1] + "',是否替换?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK) { variables[existsVarPos + 1] = rightResult; string s = variables[0]; for (int i = 1; i < variables.Length; i++) { s += "|" + variables[i]; } Properties.Settings.Default.strVariables = s; Properties.Settings.Default.Save(); txtResult.Text = "变量'" + leftValue + "'的值已替换为'" + rightResult + "'"; } } #endregion #region 存在同名常数或运算符 else if (homonymyOpe) { txtResult.Text = "存储变量失败!存在同名常数或运算符"; } #endregion #region 不存在同名变量、常数或运算符,插入变量 else { //列表variables的开始读取位置 int startPos = -1; //是否超出支持的最大变量个数 if (variables.Length < maxVarLength) { startPos = 0; } else { startPos = 2; if (MessageBox.Show("存储的变量已达到最大个数\n\n若要添加新的变量,则需要删除旧变量'" + variables[0] + "'(它的值为" + variables[1] + ")\n\n是否删除?", "提示", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { txtResult.Text = "变量未存储!"; return; } } string s = variables[startPos]; for (int i = startPos + 1; i < variables.Length; i++) { s += "|" + variables[i]; } Properties.Settings.Default.strVariables = s + "|" + leftValue + "|" + rightResult; Properties.Settings.Default.Save(); txtResult.Text = "变量'" + leftValue + "'已赋值为'" + rightResult + "'"; } #endregion } //更新变量菜单 this.变量ToolStripMenuItem.DropDownItems.Clear(); InsertVarsItem(); //更新算式输入框右键菜单 UpdateMenuRichTextBox(); //更新文本框 txtExp.Text = txtExp.Text; }
/// <summary> /// 获取变量值或用户自定义函数的计算结果 /// </summary> /// <param name="tag">变量标识符</param> private static CalNum GetVariableOrCustomFunResultValue(string tag, List<CalNum> numList) { CalNum result = null; if (numList.Count == 0)//变量 { string[] variables = Properties.Settings.Default.strVariables.Split('|'); //扫描变量键值列表 for (int i = 0; i < variables.Length; i++) { //找到变量 if (variables[i] == tag) { double d; if (double.TryParse(variables[i + 1], out d)) { result = new CalNum(d); } else { result = new CalNum(variables[i + 1]); } } } } else//用户自定义函数 { try { StringCollection funList = Properties.Settings.Default.funList; if (funList != null) { //逐个扫描存在的函数,查找函数 for (int i = 0; i < funList.Count; i++) { if (funList[i].Split('|')[0] == tag)//找到函数 { //参数个数不正确 if (numList.Count != funList[i].Split('|')[3].Split(',').Length) { throw new Exception("|参数个数不正确"); } string[] funParts = funList[i].Split('|');//分隔 StringBuilder funExpr = new StringBuilder(funParts[2]);//取出表达式 //替换表达式中的变量 for (int k = 0; k < numList.Count; k++) { bool bl; //替换,用参数的stringValue替换且两边加上括号 funExpr.Replace(Common.DeleteAnnotate(funParts[3].Split(',')[k], out bl), "(" + numList[k].stringValue + ")"); } //分段函数 if (funExpr.ToString().IndexOf("subfuns") != -1) { return subfuns(funExpr, numList);//不再进行后面的计算,返回 } //计算 bool bl1; string str = Common.DeleteAnnotate(funExpr.ToString(), out bl1);//删除注释 CalValList valList = new CalValList(str); CalResult calResult = valList.Calculate(); if (calResult.numList.Count == 1)//一个计算结果 { result = calResult.numList[0]; } else//多个计算结果 { result = new CalNum(calResult.GeneralResultToShow.Trim()); } } } } } catch (Exception ex) { throw new Exception(ex.Message + "|(函数'" + tag + "'的表达式是'" + Common.GetFunExpr(tag) + "')"); } } return result; }
/// <summary> /// 计算表达式 /// </summary> private CalResult Calculate() { CalValList valList = null; //记录表达式 memoryExp = txtExp.Text; //删除注释 txtExp.Text = Common.DeleteAnnotate(txtExp.Text, out hasAnnotate); //生成运算因子列表 valList = new CalValList(txtExp.Text); //重新显示表达式 if (hasAnnotate)//有注释 { txtExp.Text = memoryExp; } else//没有注释 { txtExp.Text = valList.nomalStringExpression; } CalResult result = null; if (this.单步计算ToolStripMenuItem.Checked)//单步计算 { completeSteps++; for (int i = 0; i < completeSteps; i++) { //优先级列表为空的情况 if (valList.levelList.Count == 0) { result = valList.CalculateOneStep(); } if (valList.levelList.Count > 0)//如果优先级尚未处理完毕 { result = valList.CalculateOneStep(); } } } else//一次性计算最终结果 { result = valList.Calculate();//计算 } return result; }