//and private static CalNum and(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { if (numList[0].DoubleValue.ToString().IndexOf("E") == -1 && numList[0].DoubleValue.ToString().IndexOf("E") == -1 && (numList[0].DoubleValue.ToString().IndexOf(".") != -1 || numList[1].DoubleValue.ToString().IndexOf(".") != -1)) { throw (new Exception("不支持小数")); } else { result = new CalNum((long)numList[0].DoubleValue & (long)numList[1].DoubleValue); } } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 求平均数 /// </summary> private static CalNum average(List<CalNum> numList) { CalNum result = null; double sum = 0; if (numList.Count != 0) { for (int i = 0; i < numList.Count; i++) { sum += numList[i].DoubleValue; } result = new CalNum(sum / numList.Count); } return result; }
/// <summary> /// sinh /// </summary> private static CalNum Cal_Sinh(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { result = new CalNum(Math.Sinh(numList[0].DoubleValue)); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 获取数字 /// </summary> private CalNum GetNum(ref string str) { CalNum result = null; result = new CalNum(str); //更新str str = ""; return result; }
/// <summary> /// 组合 /// </summary> private static CalNum Cal_nCr(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { result = new CalNum(Common.Fac((int)numList[0].DoubleValue) / (Common.Fac((int)numList[0].DoubleValue - (int)numList[1].DoubleValue) * Common.Fac((int)numList[1].DoubleValue))); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 加 /// </summary> private static CalNum Cal_Plus(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { result = new CalNum(numList[0].DoubleValue); } else if (numList.Count == 2) { //转换成整数再运算,结果再转换成小数 int decimalLength = GetDecimalLength(numList[0].DoubleValue, numList[1].DoubleValue); result = new CalNum((numList[0].DoubleValue * Math.Pow(10, decimalLength) + numList[1].DoubleValue * Math.Pow(10, decimalLength)) / Math.Pow(10, decimalLength)); } else { MakeException("参数个数不正确"); } return result; }
//Lsh private static CalNum Lsh(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { if (numList[0].DoubleValue.ToString().IndexOf("E") == -1 && numList[0].DoubleValue.ToString().IndexOf("E") == -1 && (numList[0].DoubleValue.ToString().IndexOf(".") != -1 || numList[1].DoubleValue.ToString().IndexOf(".") != -1)) { throw (new Exception("不支持小数")); } else { int length1 = Convert.ToString((long)numList[0].DoubleValue, 2).Length; int length2 = (int)numList[1].DoubleValue; if (length1 + length2 > 63) { MakeException("溢出"); } result = new CalNum((long)numList[0].DoubleValue << (int)numList[1].DoubleValue); } } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// log /// </summary> private static CalNum Cal_Log(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { result = new CalNum(Math.Log10(numList[0].DoubleValue)); } //两个参数的情况 else if (numList.Count == 2) { result = new CalNum(Math.Log(numList[0].DoubleValue, numList[1].DoubleValue)); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 度分秒与小数形式相互转换 /// </summary> private static CalNum dms(List<CalNum> numList) { CalNum result = null; double d = 0; double f = 0; double m = 0; if (numList.Count == 1) { d = Math.Floor(numList[0].DoubleValue); f = (numList[0].DoubleValue - d) * 60; m = (f - Math.Floor(f)) * 60; result = new CalNum(d.ToString() + "| 度 |" + Math.Floor(f).ToString() + "| 分 |" + m.ToString() + "| 秒"); } else if (numList.Count == 2) { result = new CalNum(numList[0].DoubleValue + numList[1].DoubleValue / 60); } else if (numList.Count == 3) { result = new CalNum(numList[0].DoubleValue + numList[1].DoubleValue / 60 + numList[2].DoubleValue / 3600); } else { MakeException("参数个数不正确"); } return result; }
/// <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> /// <param name="coefficient">换算系数</param> private static CalNum Conversion(double coefficient, List<CalNum> numList) { CalNum result = null; double doubleResult = numList[2].DoubleValue * coefficient; string strResult = numList[2].DoubleValue.ToString() + "|" + numList[0].stringValue + " = |" + doubleResult.ToString() + "|" + numList[1].stringValue; result = new CalNum(doubleResult, strResult); return result; }
/// <summary> /// 十进制转换成八进制 /// </summary> private static CalNum Cal_ToO(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { if (numList[0].DoubleValue.ToString().IndexOf("E") == -1 && numList[0].DoubleValue.ToString().IndexOf(".") != -1) { throw (new Exception("不支持小数")); } result = new CalNum(Convert.ToString((long)numList[0].DoubleValue, 8)); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 替换运算因子 /// </summary> /// <param name="num">用于替换的操作数</param> /// <param name="count">要替换的运算因子的个数</param> /// <param name="pos">替换位置</param> private void ReplaceVal(CalNum num, int count, int pos) { valList[pos] = new CalVal(num); valList.RemoveRange(pos + 1, count - 1); //左右括号同时存在,处理左右括号 if (pos >= 1 && valList[pos - 1].OpeType == OpeType.leftParenthesis && pos + 1 < valList.Count && valList[pos + 1].OpeType == OpeType.rightParenthesis) { //如sin(9-7),average(9-7) if (!(pos >= 2 && valList[pos - 2].OpeType == OpeType.right)) { //删除左右括号 valList[pos - 1] = valList[pos]; valList.RemoveRange(pos, 2); } } }
/// <summary> /// 弧度转换成角度 /// </summary> private static CalNum Cal_Degree(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { result = new CalNum(numList[0].DoubleValue * 180 / Math.PI); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 产生随机数 /// </summary> private static CalNum Rnd(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { Random rnd = new Random(); result = new CalNum(rnd.Next((int)numList[0].DoubleValue, (int)(numList[1].DoubleValue + 1))); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// !(阶乘) /// </summary> private static CalNum Cal_Fac(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { int n; try { n = int.Parse(numList[0].DoubleValue.ToString()); } catch { throw (new Exception("阶乘的操作数必须是整数")); } result = new CalNum(Common.Fac(n)); } else { MakeException("参数个数不正确"); } return result; }
//Rsh private static CalNum Rsh(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { if (numList[0].DoubleValue.ToString().IndexOf("E") == -1 && numList[0].DoubleValue.ToString().IndexOf("E") == -1 && (numList[0].DoubleValue.ToString().IndexOf(".") != -1 || numList[1].DoubleValue.ToString().IndexOf(".") != -1)) { throw (new Exception("不支持小数")); } else { int length1 = Convert.ToString((long)numList[0].DoubleValue, 2).Length; int length2 = (int)numList[1].DoubleValue; string str = null; if (length2 > 63) { MakeException("溢出"); } if (length2 <= length1) { str = Convert.ToString((long)numList[0].DoubleValue, 2).Substring(length1 - length2, length2); } else { str = Convert.ToString((long)numList[0].DoubleValue, 2); for (int i = 0; i < length2 - length1; i++) { str = str.Insert(0, "0"); } } double d = 0; for (int i = 0; i < str.Length; i++) { if (str[i] != '0') { d += 1 / Math.Pow(2, (i + 1)); } } result = new CalNum(((long)numList[0].DoubleValue >> (int)numList[1].DoubleValue) + d); } } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 乘 /// </summary> private static CalNum Cal_Multiply(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { result = new CalNum(numList[0].DoubleValue * numList[1].DoubleValue); } else { MakeException("参数个数不正确"); } return result; }
/// <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 static CalNum Cal_O(List<CalNum> numList) { CalNum result = null; if (numList.Count == 1) { result = new CalNum(Convert.ToDouble(Convert.ToInt64(numList[0].stringValue, 8))); } else { MakeException("参数个数不正确"); } return result; }
/// <summary> /// 样本标准方差 /// </summary> private static CalNum SwatchStandardVariance(List<CalNum> numList) { CalNum result = null; //特殊情况 if (numList.Count == 1) { return new CalNum(0); } double s = 0; double avg = average(numList).DoubleValue; for (int i = 0; i < numList.Count; i++) { s += Math.Pow(numList[i].DoubleValue - avg, 2); } s /= (numList.Count - 1); s = Math.Sqrt(s); result = new CalNum(s); return result; }
/// <summary> /// 乘方 /// </summary> private static CalNum Cal_Pow(List<CalNum> numList) { CalNum result = null; if (numList.Count == 2) { result = new CalNum(Math.Pow(numList[0].DoubleValue, numList[1].DoubleValue)); } else { MakeException("参数个数不正确"); } if (double.IsInfinity(result.DoubleValue)) { MessageBox.Show("指数运算'^'的运算结果为无穷大,可能会导致'log'等对数运算出现错误", "警告"); } return result; }
/// <summary> /// 计算 /// </summary> /// <param name="ope">运算符</param> /// <param name="numList">参数列表</param> public static CalNum Calculate(CalOpe ope, List<CalNum> numList) { CalNum result = null; try { switch (ope.tag) { //下面是运算符 case "+": result = Cal_Plus(numList); break; case "-": result = Cal_Minus(numList); break; case "*": result = Cal_Multiply(numList); break; case "/": result = Cal_Divide(numList); break; case "Mod": case "mod": result = Cal_Mod(numList); break; case "^": result = Cal_Pow(numList); break; case "Exp": case "exp": result = Cal_Exp(numList); break; case "ln": result = Cal_Ln(numList); break; case "log": result = Cal_Log(numList); break; case "sqrt": result = Cal_Sqrt(numList); break; case "sin": result = Cal_Sin(numList); break; case "cos": result = Cal_Cos(numList); break; case "tan": result = Cal_Tan(numList); break; case "asin": result = Cal_Asin(numList); break; case "acos": result = Cal_Acos(numList); break; case "atan": result = Cal_Atan(numList); break; case "sinh": result = Cal_Sinh(numList); break; case "cosh": result = Cal_Cosh(numList); break; case "tanh": result = Cal_Tanh(numList); break; case "nCr": //组合 case "ncr": result = Cal_nCr(numList); break; case "nAr": //排列 case "nar": result = Cal_nAr(numList); break; case "!": result = Cal_Fac(numList); break; case "%": result = Cal_Per(numList); break; case "度": result = Cal_Du(numList); break; case "toDegree": result = Cal_Degree(numList); break; case "BIN": //二进制 result = Cal_B(numList); break; case "OCT": //八进制 result = Cal_O(numList); break; case "HEX": //十六进制 result = Cal_H(numList); break; case "toB": //二进制 result = Cal_ToB(numList); break; case "toO": //八进制 result = Cal_ToO(numList); break; case "toH": //十六进制 result = Cal_ToH(numList); break; //下面是常数 case "PI": case "pi": result = new CalNum(Math.PI); break; case "e": result = new CalNum(Math.E); break; case "rnd": Random rnd = new Random(); result = new CalNum(rnd.NextDouble()); break; //下面是函数 case "avg": result = average(numList); break; case "sum": result = sum(numList); break; case "conv": result = UnitConversion(numList); break; case "s": result = SwatchStandardVariance(numList); break; case "dms": result = dms(numList); break; //下面是逻辑运算 case "and": case "And": result = and(numList); break; case "or": case "Or": result = or(numList); break; case "xor": case "Xor": result = xor(numList); break; case "not": case "Not": result = not(numList); break; //下面是位移运算符 case ">>": case "Rsh": result = Rsh(numList); break; case "<<": case "Lsh": result = Lsh(numList); break; //其他运算符 case "sgn": case "Sgn": case "Sign": case "sign": result = sgn(numList); break; case "int": case "Int": result = Int(numList); break; case "Abs": case "abs": result = abs(numList); break; case "Rnd": result = Rnd(numList); break; //分段函数 case "subfuns": MakeException("该函数不能这样使用"); break; //变量或用户自定义函数 default: result = GetVariableOrCustomFunResultValue(ope.tag, numList); break; } } catch (Exception ex) { throw (new Exception("在'" + ope.tag + "'附近可能存在错误:" + ex.Message)); } if (result == null) { throw (new Exception("在'" + ope.tag + "'附近可能存在错误")); } if (result.stringValue == "非数字") { throw (new Exception("'" + ope.tag + "'运算的计算结果非数字")); } return result; }
/// <summary> /// 构造函数 /// </summary> public CalVal(CalNum num) { this.num = num; this.type = ValType.Number; }
/// <summary> /// 获取数字 /// </summary> private CalNum GetNum(ref string str, int opePos) { CalNum result = null; result = new CalNum(str.Substring(0, opePos)); //更新str str = str.Substring(opePos); return result; }