WEB开发网
开发学院软件开发C语言 用c#编写的无限位数计算 阅读

用c#编写的无限位数计算

 2010-09-30 21:05:42 来源:WEB开发网   
核心提示:加法和减法简单,就是用一个数组来保存每一位上的数字,用c#编写的无限位数计算,然后从后往前一位一位的加减,加法记得前面会进一,我先贴出最底层的无符号无浮点运算,计算参数均为StringBuilder类型,减法则要把前面多余的“0”去掉;乘法,你就在草稿纸上做下笔算吧

加法和减法简单,就是用一个数组来保存每一位上的数字,然后从后往前一位一位的加减,加法记得前面会进一,减法则要把前面多余的“0”去掉;

乘法,你就在草稿纸上做下笔算吧,就是两个数组相应位数撒谎能够的数字相乘,分别在后面加上这两个数位后面的“0”,比如:

234*678=2*6*100*100+2*7*100*10+。。。。+4*8

是否看的明白?就是小学时老师怎么教你算你就怎么算,把电脑当成小学生就行了,这里要用到前面的加法;

除法:先拿被除数前面和除数相同位数的数和除数的倍数进行比较,这里的倍数计算就是前面的乘法,把最大倍数放进答案的最高位,以此类推,再把余下的数*10+后面一位,继续计算,直到最后一位;

下面是我写的代码,我先贴出最底层的无符号无浮点运算,计算参数均为StringBuilder类型,方便转换

(此代码仅供参考,不得参与商业活动)

static internal class Calculate
    {
        static private int[] operand1;
        static private int[] operand2;
        static private IList<int> result;
        /// <summary>
        /// 加法
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static internal StringBuilder Addition(StringBuilder a, StringBuilder b)
        {
            SetOperand(a, b);
            try
            {
                Reverse();
                int count = (operand1.Length > operand2.Length) ? operand1.Length : operand2.Length;
                int op1, op2, upNum = 0;
                for (int i = 0; i < count; i++)
                {
                    op1 = (i >= operand1.Length) ? 0 : operand1[i];
                    op2 = (i >= operand2.Length) ? 0 : operand2[i];
                    int temp = op1 + op2 + upNum;
                    if (temp < 10)
                    {
                        result.Insert(0, temp);
                        upNum = 0;
                    }
                    else
                    {
                        result.Insert(0, temp % 10);
                        upNum = temp / 10;
                    }
                    if ((i == (count - 1)) && upNum > 0) result.Insert(0, upNum);
                }
            }
            catch { result = new List<int>() { 0,0,0}; }
            return GetResult();
        }
        /// <summary>
        /// 减法
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static internal StringBuilder Subtraction(StringBuilder a, StringBuilder b)
        {
            SetOperand(a, b);
           
            try
            {
                Reverse();
                bool desc = isDesc(a, b);
                int[] opList1 = desc ? operand2 : operand1;
                int[] opList2 = desc ? operand1 : operand2;
                int count = (opList1.Length > opList2.Length) ? opList1.Length : opList2.Length;
                int op1, op2, upNum = 0;
                for (int i = 0; i < count; i++)
                {
                    op1 = (i >= opList1.Length) ? 0 : opList1[i];
                    op2 = (i >= opList2.Length) ? 0 : opList2[i];
                    int temp = op1 - op2 - upNum;
                    if (temp >= 0)
                    {
                        result.Insert(0, temp);
                        upNum = 0;
                    }
                    else
                    {
                        result.Insert(0, temp + 10);
                        upNum = 1;
                    }
                }
                for (int i = 0; i < count; i++)
                {
                    if (result[0] == 0)
                        result.RemoveAt(0);
                    else
                        break;
                }
            }
            catch { SetOperand(a, b); }
            return GetResult();
        }
        /// <summary>
        /// 乘法
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static internal StringBuilder Multiplication(StringBuilder a, StringBuilder b)
        {
            SetOperand(a, b);
           
            StringBuilder strResult = new StringBuilder("0");
            try
            {
                int[] opList1 = operand1;
                int[] opList2 = operand2;
                for (int i = 0; i < opList1.Length; i++)
                {
                    for (int j = 0; j < opList2.Length; j++)
                    {
                        string temp = (opList1[i] * opList2[j]).ToString();
                            Console.Write(temp);
                        for (int t = 0; t < (opList1.Length - i - 1) + (opList2.Length - j - 1); t++)
                        {
                            temp = temp + "0";
                        }
                        strResult = Addition(strResult, new StringBuilder(temp));
                    }
                }
            }
            catch { SetOperand(a, b); }
            return strResult;
            //return GetResult();
        }
        /// <summary>
        /// 除法
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static internal StringBuilder Division(StringBuilder a, StringBuilder b)
        {
            SetOperand(a, b);
            StringBuilder strResult = new StringBuilder();
            try
            {
                StringBuilder opStr1 = clearSB(a);
                StringBuilder opStr2 = clearSB(b);
                if (isDesc(a, b))
                {
                    strResult.Append("0");
                }
                else
                {
                    StringBuilder upNum = new StringBuilder("0");
                    for (int i = 0; i <= (opStr1.Length - opStr2.Length); i++)
                    {
                        StringBuilder temp = new StringBuilder();
                        if (i == 0) temp.Append(opStr1.ToString().Substring(i, b.Length));
                        else temp.Append(opStr1.ToString().Substring(i + b.Length - 1, 1));
                        temp = Addition(clearSB(Multiplication(upNum, new StringBuilder("10"))), clearSB(temp));
                        for (int j = 9; j >= 0; j--)
                        {
                            StringBuilder tempSB = Multiplication(opStr2, new StringBuilder(j.ToString()));
                            if (!isDesc(clearSB(temp), clearSB(tempSB)))
                            {
                                strResult.Append(j.ToString());
                                upNum = clearSB(Subtraction(temp, clearSB(tempSB)));
                                break;
                            }
                        }
                    }
                }
            }
            catch { SetOperand(a, b); }
            return clearSB(strResult);
            //return GetResult();
        }
        /// <summary>
        /// 清除StringBuilder前面的0
        /// </summary>
        /// <param name="operand"></param>
        /// <returns></returns>
        static private StringBuilder clearSB(StringBuilder operand)
        {
            int count = operand.Length;
            for (int i = 0; i < count; i++)
            {
                if (operand[0] == '0')
                    operand.Remove(0,1);
                else
                    break;
            }
            return operand;
        }
        /// <summary>
        /// 是否后者比前者大
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        static private bool isDesc(StringBuilder a, StringBuilder b)
        {
            int[] opList1 = PutListByString(a.ToString());
            int[] opList2 = PutListByString(b.ToString());
            bool desc = false;
            if (opList2.Length > opList1.Length) desc = true;
            if (opList2.Length == opList1.Length)
            {
                for (int i = 0; i < opList1.Length; i++)
                {
                    if (opList1[i] > opList2[i])
                    {
                        desc = false;
                        i = opList1.Length;
                    }
                    else if (opList2[i] > opList1[i])
                    {
                        desc = true;
                        i = opList1.Length;
                    }
                }
            }
            return desc;
        }
        /// <summary>
        /// 倒序 被操作数组
        /// </summary>
        static private void Reverse()
        {
            int[] Result1 = new int[operand1.Length];
            for (int i = 0; i < operand1.Length; i++)
            {
                Result1[i] = operand1[operand1.Length - i - 1];
            }
            operand1 = Result1;
            int[] Result2 = new int[operand2.Length];
            for (int i = 0; i < operand2.Length; i++)
            {
                Result2[i] = operand2[operand2.Length - i - 1];
            }
            operand2 = Result2;
        }
        /// <summary>
        /// 得到答案 string
        /// </summary>
        /// <returns>string</returns>
        static private StringBuilder GetResult()
        {
            StringBuilder strResult = new StringBuilder();
            for (int i = 0; i < result.Count; i++)
            {
                strResult.Append(result[i]);
            }
            return strResult;
        }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        static private void SetOperand(StringBuilder a, StringBuilder b)
        {
            operand1 = PutListByString(a.ToString());
            operand2 = PutListByString(b.ToString());
            result = new List<int>();
        }
        /// <summary>
        /// 转化字符串为数组
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        static private int[] PutListByString(string str)
        {
            int[] res = new int[str.Length];
            try
            {
                for (int i = 0; i < str.Length; i++)
                    res[i] = int.Parse(str.Substring(i, 1));
            }
            catch { res = new int[] { 0 }; }
            return res;
        }
    }

Tags:编写 无限 位数

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接