现在的位置: 首页 > 综合 > 正文

C# 大数的计算,普通的int,Long不能满足,自定义大数据的加减乘除(仅实现加法和乘法)

2013年01月21日 ⁄ 综合 ⁄ 共 3426字 ⁄ 字号 评论关闭

在项目中遇到一个问题,自增的数据,当数据达到很大时 ,进行自增会出现问题。

首先创建一个运算器接口:

   //运算器接口
    interface ICalculator
    {
        //实现大数的四则运算,二元运算,参数为字符型
        string add(string param1,string param2);
        string multiply(string param1, string param2);

        //未实现的功能
        //void subtract(string param1, string param2);
        //void divide(string param1, string param2); 
    }

然后,写一个实现类,继承运算器接口,实现其方法

 class Calculator:ICalculator
    {
        #region ICalculator 成员

        //大整数加法
        string ICalculator.add(string param1, string param2)
        {
            //将字符串转换成字符数组
            char[] ch1 = param1.ToCharArray();
            char[] ch2 = param2.ToCharArray();

            //将字符串数组反转
            Array.Reverse(ch1);
            Array.Reverse(ch2);

            //调用数组加法
            char[] ch = this.adds(ch1, ch2);
            //将字符串数组再反转回去
            Array.Reverse(ch);

            //将结果转化成字符串型           
            return new string(ch);

        }

        //大整数乘法
        string ICalculator.multiply(string param1, string param2)
        {
            char[] ch1 = param1.ToCharArray();
            char[] ch2 = param2.ToCharArray();
            char[] ch3 = initArray(1);
            Array.Reverse(ch1);
            Array.Reverse(ch2);
            for (int i = 0; i < ch2.Length; i++)
            {
                int n = int.Parse(ch2[i].ToString());
                char[] chp = addZeros(multiplies(n, ch1), i);
                ch3 = adds(chp, ch3);
            }

            Array.Reverse(ch3);
            return new string(ch3);

        }

        #endregion

        //数组加法,字符串运算时转化成字符数组来计算的
        private char[] adds(char[] ch1, char[] ch2)
        {
            //取较长数组长度
            int length = (ch1.Length > ch2.Length ? ch1.Length : ch2.Length);

            //调用自定义方法代替规范化数组
            char[] cha = initArray(ch1, length);
            char[] chb = initArray(ch2, length);
            char[] chc = initArray(length + 1);

            for (int i = 0; i < length; i++)
            {
                //取字符数组第i个元素化成整型
                int num1 = int.Parse(cha[i].ToString());
                int num2 = int.Parse(chb[i].ToString());
                int num3 = int.Parse(chc[i].ToString());

                //将整数结算结果化成字符数组的形式
                char[] chp = (num1 + num2 + num3).ToString().ToCharArray();
                //将结果填充到存放结果的数组中
                if (chp.Length == 2)
                {
                    chc[i] = chp[1];
                    chc[i + 1] = chp[0];
                }
                else chc[i] = chp[0];
            }

            //返回结果消除高位的零            
            return delZeros(chc);
        }

        //个位整数与数组乘法
        private char[] multiplies(int n, char[] chs)
        {
            //存放结果的数组
            char[] cht = initArray(chs.Length + 1);
            for (int i = 0; i < chs.Length; i++)
            {
                int s = int.Parse(chs[i].ToString());
                int t = int.Parse(cht[i].ToString());
                char[] chp = (n * s + t).ToString().ToCharArray();
                if (chp.Length == 2)
                {
                    cht[i] = chp[1];
                    cht[i + 1] = chp[0];
                }
                else cht[i] = chp[0];
            }

            //返回结果消除高位的零            
            return delZeros(cht);
        }

        //初始化字符串数组,各元素为'0'
        private char[] initArray(int n)
        {
            char[] ch = new char[n];
            for (int i = 0; i < n; i++)
            {
                ch[i] = '0';
            }
            return ch;
        }

        //规范化数组,实现将原数组中元素复制到目标数组
        //如果目标数组长度小于原数组则截取,
        //如长度大于原数组则补零
        private char[] initArray(char[] cha, int n)
        {
            char[] chb = new char[n];
            int i;
            for (i = 0; i < n && i < cha.Length; i++)
            {
                chb[i] = cha[i];
            }
            while (i < n)
            {
                chb[i] = '0';
                i++;
            }
            return chb;
        }

        //数组添零,即将原数以十数量级提升
        private char[] addZeros(char[] ch, int n)
        {
            char[] cho = new char[ch.Length + n];
            int i;

            for (i = 0; i < n; i++)
            {
                cho[i] = '0';
            }
            for (; i < cho.Length; i++)
            {
                cho[i] = ch[i - n];
            }
            return cho;
        }

        //消除高位的零,如果全为零的话,保留一个
        private char[] delZeros(char[] ch)
        {
            int i;
            for (i = 0; i < ch.Length - 1; i++)
            {
                if (ch[ch.Length - 1 - i] != '0')
                    break;
            }
            return initArray(ch, ch.Length - i);
        }
       
    }

最后写一个调用类:

class MyMath
    {
        //参数一
        string param1 = "";
        public string Param1
        {
            set
            {
                Regex r1 = new Regex("^(0|[1-9][0-9]*)$");//只能输入零和非零开头的数字

                Match m1 = r1.Match(value);

                if (!(m1.Success))
                {
                    throw new ArgumentException("输入参数不正确,只能输入零和非零开头的数字!", this.param1);
                }
                this.param1 = value;
            }

            get
            {
                return this.param1;
            }

        }
      
        //参数二
        string param2 = "";
        public string Param2
         {
            set
            {
                Regex r2 = new Regex("^(0|[1-9][0-9]*)$");//只能输入零和非零开头的数字

                Match m2 = r2.Match(value);

                if (!(m2.Success))
                {
                    throw new ArgumentException("输入参数不正确,只能输入零和非零开头的数字!", this.param2);
                }
                this.param2 = value;
            }

            get
            {
                return this.param2;
            }
        }

        //运算结果
        string result = "";
        public string Result
        {
          get { return result; }
        }

        //运算器,接口类型
        ICalculator calculator = null;
        //当修改接口实现类的时候不需要修改应用接口类的代码
        internal ICalculator Calculator
        {
            get { return calculator; }
            set { calculator = value; }
        }

        public void add()
        {
            result = calculator.add(param1,param2);
 
        }

        public void multiply()
        {
            result = calculator.multiply(param1,param2);
        }
     
    }

创建一个winform界面,

如下

源码:http://download.csdn.net/detail/zhuni_xingfu/5572465

抱歉!评论已关闭.