加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

大数运算

发布时间: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");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读