大数运算
发布时间:2020-12-14 03:10:20 所属栏目:大数据 来源:网络整理
导读:加法: 逐位相加,要考虑到进位的情况。 减法:逐位相减,要考虑到借位的情况。 乘法:第一个乘数不动,循环第二个乘数的每一位,每一位先做循环加法,在根据位置对加的结果补0,最后把结果累加起来。 除法:循环从被除数中减去除数,减去多少次结果就是多少
加法: 逐位相加,要考虑到进位的情况。 减法:逐位相减,要考虑到借位的情况。 乘法:第一个乘数不动,循环第二个乘数的每一位,每一位先做循环加法,在根据位置对加的结果补0,最后把结果累加起来。 除法:循环从被除数中减去除数,减去多少次结果就是多少,直接写运行很慢,做了一点优化,看操作数之间长度差是否大于1,如果大于1,则本次除数后补差距-1个0,循环可以控制在百次左右。 public class BigDataOperator { /// <summary> /// 加法 /// </summary> /// <param name="lOperand"></param> /// <param name="rOperand"></param> /// <returns></returns> public static string Add(string lOperand,string rOperand) { if (string.IsNullOrEmpty(lOperand) || string.IsNullOrEmpty(rOperand)) throw new ArgumentException("not a number"); bool isNeginative = false; if (IsNegative(lOperand) && IsNegative(rOperand)) { isNeginative = true; lOperand = lOperand.Trim('-'); rOperand = rOperand.Trim('-'); } if (IsNegative(lOperand) && !IsNegative(rOperand)) return Minus(rOperand,lOperand.Trim('-')); if (!IsNegative(lOperand) && IsNegative(rOperand)) return Minus(lOperand,rOperand.Trim('-')); string shortNumStr = lOperand; string longNumStr = rOperand; if (lOperand.Length > rOperand.Length) { shortNumStr = rOperand; longNumStr = lOperand; } StringBuilder result = new StringBuilder(); //长数加短数 逐位相加 var difference = longNumStr.Length - shortNumStr.Length; //长度差 int carry = 0;//进位 for (int i = longNumStr.Length - 1; i >= 0; i--) { var shortIndex = i - difference; var lNum = longNumStr[i] - (int)'0'; int sNum = 0; if (shortIndex >= 0) { sNum = shortNumStr[shortIndex] - (int)'0'; } var sum = lNum + sNum + carry; if (sum > 9) { carry = 1; result.Insert(0,sum - 10); } else { carry = 0; result.Insert(0,sum); } } //最后可能结果增长了一位 if (carry != 0) result.Insert(0,1); return (isNeginative ? "-" : "") + result.ToString().TrimStart('0'); } /// <summary> /// 减法 /// </summary> /// <param name="lOperand"></param> /// <param name="rOperand"></param> /// <returns></returns> public static string Minus(string lOperand,string rOperand) { if (string.IsNullOrEmpty(lOperand) || string.IsNullOrEmpty(rOperand)) throw new ArgumentException("not a number"); bool isNeginative = true; if (IsNegative(lOperand) && IsNegative(rOperand)) return Minus(rOperand.TrimStart('-'),lOperand.TrimStart('-')); if (IsNegative(lOperand) && !IsNegative(rOperand)) return Add(lOperand,"-" + rOperand); if (!IsNegative(lOperand) && IsNegative(rOperand)) return Add(lOperand,rOperand.Trim('-')); var bigNum = rOperand; var smallNum = lOperand; if (IsBigger(lOperand,rOperand)) { isNeginative = false; bigNum = lOperand; smallNum = rOperand; } if (lOperand == rOperand) return "0"; StringBuilder result = new StringBuilder(); //逐位相加 var difference = bigNum.Length - smallNum.Length; //长度差 int borrowNum = 0; //借位 for (int i = bigNum.Length - 1; i >= 0; i--) { var shortIndex = i - difference; var lNum = bigNum[i] - (int)'0' - borrowNum; int sNum = 0; if (shortIndex >= 0) { sNum = smallNum[shortIndex] - (int)'0'; } if (lNum < sNum) { borrowNum = 1; } else { borrowNum = 0; } var diff = lNum + borrowNum * 10 - sNum; result.Insert(0,diff); } return (isNeginative ? "-" : "") + result.ToString().TrimStart('0'); } /// <summary> /// 乘法 /// </summary> /// <param name="lOperand"></param> /// <param name="rOperand"></param> /// <returns></returns> public static string Multiple(string lOperand,string rOperand) { if (string.IsNullOrEmpty(lOperand) || string.IsNullOrEmpty(rOperand)) throw new ArgumentException("not a number"); bool isNeginative = true; if (!IsNegative(lOperand) && !IsNegative(rOperand)) isNeginative = false; if (IsNegative(lOperand) && IsNegative(rOperand)) isNeginative = false; lOperand = lOperand.Trim('-'); rOperand = rOperand.Trim('-'); StringBuilder result = new StringBuilder(); //逐位相加 var resultTemp = "0"; for (int i = rOperand.Length - 1; i >= 0; i--) { var num = rOperand[i] - (int)'0'; var bitemp = "0"; for (int j = 0; j < num; j++) //重复加 { bitemp = Add(bitemp,lOperand); } for (int k = 0; k < rOperand.Length - 1 - i; k++) //尾部补0 { bitemp = bitemp + "0"; } resultTemp = Add(resultTemp,bitemp); } return (isNeginative ? "-" : "") + resultTemp.TrimStart('0'); } /// <summary> /// 除法(小数舍去) /// </summary> /// <param name="lOperand"></param> /// <param name="rOperand"></param> /// <returns></returns> public static string Divided(string lOperand,string rOperand) { if (string.IsNullOrEmpty(lOperand) || string.IsNullOrEmpty(rOperand)) throw new ArgumentException("not a number"); bool isNeginative = true; if (!IsNegative(lOperand) && !IsNegative(rOperand)) isNeginative = false; if (IsNegative(lOperand) && IsNegative(rOperand)) isNeginative = false; lOperand = lOperand.Trim('-'); rOperand = rOperand.Trim('-'); if (lOperand == rOperand) return (isNeginative ? "-" : "") + '1'; if (!IsBigger(lOperand,rOperand)) return "0"; string result = "0"; var temp = lOperand; while (true) //循环减法 { var dividedNum = rOperand; var times = "1"; var differ = temp.Length - rOperand.Length;//优化 if (differ > 1) { for (int i = 0; i < differ - 1; i++) { dividedNum = dividedNum + "0"; times = times + "0"; } } temp = Minus(temp,dividedNum); if (IsNegative(temp)) { break; } result = Add(result,times); } return (isNeginative ? "-" : "") + result.TrimStart('0'); } /// <summary> /// 判断是否大于 /// </summary> /// <param name="lOperand"></param> /// <param name="rOperand"></param> /// <returns></returns> public static bool IsBigger(string lOperand,string rOperand) { if (string.IsNullOrEmpty(lOperand) || string.IsNullOrEmpty(rOperand)) throw new ArgumentException("not a number"); bool isAllNagative = false; if (IsNegative(lOperand) && !IsNegative(rOperand)) return false; if (!IsNegative(lOperand) && IsNegative(rOperand)) return true; if (IsNegative(lOperand) && IsNegative(rOperand)) { isAllNagative = true; } string shortNumStr = lOperand; string longNumStr = rOperand; if (lOperand.Length > rOperand.Length) { return isAllNagative ? false : true; } if (lOperand.Length < rOperand.Length) { return isAllNagative ? true : false; } for (int i = 0; i < lOperand.Length; i++) { if (lOperand[i] > rOperand[0]) { return isAllNagative ? false : true; } else if (lOperand[i] < rOperand[0]) { return isAllNagative ? true : false; } else { continue; } } //equal return false; } /// <summary> /// 判断是不是负数 /// </summary> /// <param name="value"></param> /// <returns></returns> public static bool IsNegative(string value) { if (string.IsNullOrEmpty(value)) throw new ArgumentException("not a number"); return value.ElementAt(0) == '-'; } } 测试: Assert.AreEqual(BigDataOperator.IsNegative("4444444444444444444444444444444444444"),false); Assert.AreEqual(BigDataOperator.IsNegative("-14444444444444444444444444444444444444"),true); Assert.AreEqual(BigDataOperator.IsBigger("5555555555555","5555555555555"),false); Assert.AreEqual(BigDataOperator.IsBigger("5555555555555","-5555555555555"),true); Assert.AreEqual(BigDataOperator.IsBigger("-5555555555555",false); Assert.AreEqual(BigDataOperator.IsBigger("66666666666666","555555555555"),true); Assert.AreEqual(BigDataOperator.IsBigger("555555555555","66666666666666"),false); //add Assert.AreEqual(BigDataOperator.Add("555555555555","67222222222221"); Assert.AreEqual(BigDataOperator.Add("555555555555","-66666666666666"),"-66222222222211"); Assert.AreEqual(BigDataOperator.Add("-555555555555","66222222222211"); Assert.AreEqual(BigDataOperator.Add("-555555555555","-67222222222221"); //minus Assert.AreEqual(BigDataOperator.Minus("555555555555","-66222222222211"); Assert.AreEqual(BigDataOperator.Minus("555555555555","67222222222221"); Assert.AreEqual(BigDataOperator.Minus("-555555555555","-67222222222221"); Assert.AreEqual(BigDataOperator.Minus("-555555555555","66222222222211"); //multy Assert.AreEqual(BigDataOperator.Multiple("4236586974332423432","13216545765875841324"),"55993045637377932557226829234811503968"); Assert.AreEqual(BigDataOperator.Multiple("4236586974332423432","-13216545765875841324"),"-55993045637377932557226829234811503968"); Assert.AreEqual(BigDataOperator.Multiple("-4236586974332423432","55993045637377932557226829234811503968"); //divide Assert.AreEqual(BigDataOperator.Divided("32464576587684354324325632454325","666623666466626666"),"48700006046529"); Assert.AreEqual(BigDataOperator.Divided("-32464576587684354324325632454325","-48700006046529"); Assert.AreEqual(BigDataOperator.Divided("32464576587684354324325632454325","-666623666466626666"),"-48700006046529"); Assert.AreEqual(BigDataOperator.Divided("-32464576587684354324325632454325","48700006046529"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |