C#大数用数组实现

相册地址:

http://hi.baidu.com/delaprelson/album/%B4%F3%CA%FD%BC%C6%CB%E3

 

乘除的两个重载先不拿出来SHOW人了

所谓大数,就是超出数据类型的数值,C#能存储的最大数据类型是decimal,如果一个数的大小超出它的

存储范围,就会溢出。
解决方法是用一个长度足够大的数组,按数组的每一个元素存储4个位长的数,这样就能用数组来表示已

个足够大的数。
如521412468811643779611167425,在C#中任何一种数据类型都无法存储,如果用数组,按每4位为一个数

组元素,就可以存储起来。但是在运行效率方面有点慢——毕竟用到了数组,内存开销肯定是大了一点的


用数组表示例如 short b[] = new short[100];
b[0]=7425;b[1]=1116;b[2]=7796;b[3]=1643;b[4]=6881;b[5]=4124;

//最后一个,按照任何数 假设把这个数设为x,那么有x%4<4,就是说,最后一个数的长度要么等于4,要么

就小于4且大于0,所以:
b[6]=521;
然后在最后一位设置校检位,用来表明该数是一个正数,或者是负数,假设,正数为-1,负数为-2
就有:
521412468811643779611167425,
b[7]=-1;
如果-521412468811643779611167425,
b[7]=-2;
如果有小数部分还要另外设置

用途: 可以用来实现RSA加密算法,当然了 用C#作算法,要考虑速度,本人只是偏爱C#编程
在这里用一个枚举来表示
     /// <summary>
        /// 校检正负数,并作为结束符
        /// </summary>
        internal enum NumberCheck : short {

            /// <summary>
            /// 如果是正数,在数组的最后一个元素加入该枚举值(-1表示)
            /// </summary>
            Positive = -1,
            /// <summary>
            /// 如果是负数,在数组的最后一个元素加入该枚举值(-2表示)
            /// </summary>
            Negative = -2,
            /// <summary>
            /// 小数点标记位,在数组的第一个元素加入该枚举值(-3表示)
            /// </summary>
            FloatingPointFlag = -3,
            /// <summary>
            /// 小数点标记位,意味着没有小数部分,或者截除小数部分,
            /// 在数组的第一个元素加入该枚举值(-4表示)
            /// </summary>
            NonFloatingPointFlag = -4
        };
    }
如果用一个类或者结构将这样的“类型”封装起来,并实现运算符重载,就能对该类型实现+-/×等运算

;如果实现转换运算符,还可以同系统自带的数据类型一起进行运算,某种意义上,也成为了一种用于运

算的数据类型。
下面是源代码,将上述的类型封装成结构,名为BigNumber ,只提供+-,×/就不提供了
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.EnterpriseServices;
/*
 * written by Feng
 * since 27-may-09 13:13:18

*/

 

namespace FengCreateCLRDll {
    namespace BigNumberCount {
        //入口
        //1.用一个纯数字的string
        //2.同上 char[]
        //3一个short数组,格式 如:1,000,000,1 ->short [] a : a[0]=1,进四位,a[1]=1000
        // a[2]=校检位:正数,负数,(正浮点数,负浮点数:在小数点的位置校检)

        //计算精确位
        //对于整数部分,不必限制位
        //对于小数部分,精确到小数点后的多少位:无理数计算,如:11÷7

        //7亿9千万 <= cout <8亿  个list元素的个数 说明至少有4*7亿9千万的数位(即 31.4亿个长

度)可以被储存在BigNumber结构中

        //运算符重载
        //转换 二 八 十六 进制 用short数组表示 ,转换成易读性的string

        //运用
        //RAS算法

        //整数部分,校检位在最后一个元素中
        //小数部分,校检位在第一个元素
        /// <summary>
        /// 用来表示“大数”的数据类型,这样的“大数”一般是超出内置数据类型的数字,可通过运

算符重载
        /// 进行运算.(未完)
        /// </summary>

 

 [SerializableAttribute]
        [ComVisibleAttribute(true)]
        [Guid("c3454a74-9742-4408-89aa-7395e32855e6")]
        public struct BigNumber {

            //关于线程同步,由于这是一个结构,在运算符重载的操作数--参数,都是外部实参的副本
            //,也就是值拷贝,而不是引用拷贝,因此在多线程里使用同一个对象,除非作为参数实参

的对象
            //在外面的线程被修改,并且只有在调用重载之前修改,才有可能引起参数上的改变,从而

引起
            //对象不同步,如果是在调用重载之后,才修改该值的,不会影响。

 

            //字段
            /// <summary>
            /// 整数部分
            /// </summary>
            List<short> IntegerPart;//包含最后一个校检位
            /// <summary>
            /// 小数部分
            /// </summary>
            List<short> FractionPart;//第一位除以1*10^(4*1),第二个除以10^(4*2)
            /// <summary>
            /// 获取整数部分的值,用数组表示
            /// </summary>
            public short[] INTERGETpart {
                get {
                    return this.IntegerPart.ToArray();
                }
            }
            /// <summary>
            /// 获取小数部分的值,用数组表示
            /// </summary>
            public short[] FRACTIONpart {
                get {
                    return this.FractionPart.ToArray();
                }
            }
            /// <summary>
            /// 获取一个数的长度
            /// </summary>
            internal static short Length(short specValue) {
                short count = 1;
                short t = specValue;
                while((t /= 10) > 0)
                    count++;
                return count;
            }
            static BigNumber zero = new BigNumber("0");
            /// <summary>
            /// 返回一个零值的BigNumber对象
            /// </summary>
            public static BigNumber Zero {
                get {
                    return zero;
                }
            }
            /// <summary>
            /// 将BigNumber结构储存的值转化为易于理解的十进制数,用string表示
            /// </summary>
            internal string ReadableBigNumber {
                get {
                    string rv = "";

                    short[] ip = this.INTERGETpart;
                    short[] fp = this.FRACTIONpart;

                    #region 整数

                    int l = ip.Length;


                    if(ip[l - 1] == (short)NumberCheck.Negative)   //获取标记位
                        rv += "-";
                    else
                        rv += "+";

                    rv += ip[l - 2].ToString();//最高位的值
                    if(ip.Length > 2) {
                        short regL = 0;
                        for(int maxi = l - 3; maxi >= 0; maxi--) {
                            //从第二个元素开始,如果只有3位,2位,1位,->在前面填充4-n个零
                            regL = Length(ip[maxi]);
                            switch(regL) {
                                case 1:
                                rv += "000" + ip[maxi].ToString();
                                break;
                                case 2:
                                rv += "00" + ip[maxi].ToString();
                                break;
                                case 3:
                                rv += "0" + ip[maxi].ToString();
                                break;
                                case 4:
                                rv += ip[maxi].ToString();
                                break;

                            }

                        }

                    }
                    #endregion 整数

                    #region 小数
                    if(fp[fp.Length - 1] == (short)NumberCheck.NonFloatingPointFlag)
                        return rv;
                    int fl = fp.Length;
                    rv += ".";
                    short fregL = 0;
                    for(int mini = 1; mini <= fl - 1; mini++) {
                        fregL = Length(fp[mini]);
                        switch(fregL) {
                            case 1:
                            rv += "000" + fp[mini].ToString();
                            break;
                            case 2:
                            rv += "00" + fp[mini].ToString();
                            break;
                            case 3:
                            rv += "0" + fp[mini].ToString();
                            break;
                            case 4:
                            rv += fp[mini].ToString();
                            break;


                        }

 

                    }

                    #endregion 小数

 


                    return rv;
                }
               
            }

            //静态字段
            int ReserveLength;
            //静态属性
            /// <summary>
            /// 设置或者获取在计算后得到小数点后保留的位数,默认保留20位小数,前提是进行无理

数运算的情况下,采取的折衷措施,否则函数不会返回,将一直运算下去
            /// </summary>
            public int FloatingPointReserveLength {
                get {
                    return ReserveLength;
                }
                set {
                    ReserveLength = value;
                }
            }

            /*  internal BigNumber() {
                  this.IntegerPart = new List<short>();
                  this.FractionPart = new List<short>();
                  this.ReserveLength = 10;
                  this.IntegerPart.Add(0);
                  this.IntegerPart.Add((short)NumberCheck.Positive);
                  this.FractionPart.Add((short)NumberCheck.NonFloatingPointFlag);
              }
              */


            /// <summary>
            /// 用一个字符串表示某个超出数据类型范围的数值,存入一个数组中,通过数组间的元素

进行运算
            /// </summary>
            /// <param name="bignumber">格

式:"+4521412468811643779611167425.12454254643"</param>
            /// <remarks>正负标记:+或- 必须放在字符串的起始处,也可不用正负标记,

如"45214124688"为正数</remarks>
            public BigNumber(string bignumber) {

                object lobj = new object();
                lock(lobj) {

                    this.ReserveLength = 20;


                    //    bignumber = BigNumber.OffInvalidZero(bignumber);


                    byte[] b = ASCIIEncoding.ASCII.GetBytes(bignumber);
                    //+ :43 ,- :45 ,0 :48 , .:46,9:57
                    //检索第一个字符 + - 0
                    int startLocation = 0;//数字串的起始位
                    bool folatingPoint = false;//检索小数点是否存在,默认不存在
                    int folatingPointLocation = 0;
                    bool flag = false;// + - 标记 默认为没有+ - 标记  bignumber的第一个元素0


                    if(bignumber == "-0" || bignumber == "+0" || bignumber == "0")
                        goto _forbidden_zone;

 

                    if(bignumber.Length == 1)
                        if(b[0] < 48 || b[0] > 57)
                            throw new ArgumentException("参数 bignumber 格式不正确");
                        else
                            goto _forbidden_zone;

 

                    if(
                        b[0] != 43 && b[0] != 45 &&
                      (b[0] < 48 || b[0] > 57)
                         )
                        throw new ArgumentException("参数 bignumber 格式不正确");

 

 


                    if(b[0] != 43 && b[0] != 45)
                        flag = false;
                    else
                        flag = true;

 

                    if(flag && b[1] == 48 && b[2] != 46)
                        throw new ArgumentException("参数 bignumber 格式不正确");


                    if(!flag && b[0] == 48 && b[1] != 46)
                        throw new ArgumentException("参数 bignumber 格式不正确");

 

 


                    //+- 0.开头
                    if(flag)
                        startLocation = 1;
                    if(flag && b[1] == 48)
                        startLocation = 3;
                    if(!flag && b[0] == 48)
                        startLocation = 2;

                    //非0开头的串,查找'.'是否存在以及位置

                    for(int i = 0; i < b.Length; i++)
                        if(b[i] == 46) {
                            folatingPoint = true;
                            folatingPointLocation = i;
                            break;//第一个并记录到变量
                        }

                    if(b[b.Length - 1] == 46)
                        throw new ArgumentException("参数 bignumber 格式不正确");


                    //从startLocation开始判断非0-9的值

                    if(folatingPoint)
                        for(int i = startLocation; i < b.Length; i++)
                            if(bignumber[i] > 57 || bignumber[i] < 48) {
                                if(i == folatingPointLocation)
                                    continue;
                                throw new ArgumentException("参数 bignumber 格式不正确");

                            }

_forbidden_zone:


                    //每4个子串为一个storeBigNum元素,从字符串的高位,按每4位,填充到

storeBigNum的元素中


                    //值低位数放到storeBigNum低位元素中,按左开始,NumberCheck放在最后,便于计


                    //1234 5678 a[0]5678 a[1]1234
                    //从右到左
                    //某些位可能不足4位,例如原数:10040006->6,1004 :6->0006,如果10040006-

50006,后面相同的抵消,1004-5
                    //100040006-5-70006,后面抵消,0006 0004 1 : 4-7->14-7=7,向高位借1-

>9997,0000
                    this.IntegerPart = new List<short>();
                    this.FractionPart = new List<short>();


                    string decimal_fraction = "";//小数部分的值

                    string whole_number = "";//整数部分的值
                    if(folatingPoint)
                        decimal_fraction = bignumber.Substring(
                           folatingPointLocation + 1,
                           bignumber.Length - folatingPointLocation - 1);
                    else
                        decimal_fraction = "";

                    if(flag) {
                        if(folatingPoint)
                            whole_number = bignumber.Substring(
                                1, folatingPointLocation - 1);
                        else
                            whole_number = bignumber.Substring(
                                1, bignumber.Length - 1);


                    } else
                        if(!flag) {
                            if(folatingPoint)
                                whole_number = bignumber.Substring(
                                    0, folatingPointLocation);
                            else
                                whole_number = bignumber;


                        }

                    //Console.WriteLine(whole_number);

                    #region 小数部分
                    //按最高位(0.1 十分位)对齐,当计算时,不足的位补0对齐

                    //小数的十分位在数组里的表现是四位数,如0.1在数组里是1000
                    if(folatingPoint) {
                        this.FractionPart.Add((short)NumberCheck.FloatingPointFlag);//小数点

符号位

                        int lastvalue = decimal_fraction.Length % 4;
                        //填充0,使每个数组元素都够4位数
                        switch(lastvalue) {
                            case 1:
                            decimal_fraction += "000"; break;
                            case 2: decimal_fraction += "00"; break;
                            case 3: decimal_fraction += "0"; break;
                        }
                        int count = decimal_fraction.Length / 4;
                        int start = 0;
                        string substr = "";

                        for(int i = 0; i < count; i++) {
                            substr = decimal_fraction.Substring(start, 4);


                            this.FractionPart.Add(
                                Convert.ToInt16(substr));

                            start += 4;

 

                        }


                    } else
                        this.FractionPart.Add((short)NumberCheck.NonFloatingPointFlag);

 


                    #endregion 小数部分

                    # region 整数部分
                    //按最低位(个位)对齐
                    if(whole_number.Length <= 4)
                        this.IntegerPart.Add(
                            Convert.ToInt16(whole_number)
                               );

                    if(whole_number.Length > 4) {

                        int count = whole_number.Length / 4;//循环的次数
                        int lastvalue = whole_number.Length % 4;//最后一次的字符个数

                        int start = whole_number.Length - 4;
                        string substr = "";

                        for(int i = 0; i < count; i++) {
                            substr = whole_number.Substring(start, 4);//串的最右边的子串,作

为storeBigNum的地位元素值
                            this.IntegerPart.Add(
                                Convert.ToInt16(substr)
                            );


                            start -= 4;
                        }
                        if(lastvalue != 0)
                            this.IntegerPart.Add(
                                Convert.ToInt16(whole_number.Substring(0, lastvalue)));

                    }

 


                    #endregion 整数部分
                    #region 正负校检位
                    if(flag && b[0] == 45)

                        this.IntegerPart.Add((short)NumberCheck.Negative);

                    else
                        this.IntegerPart.Add((short)NumberCheck.Positive);
                    #endregion 正负校检位

                }
            }
            internal BigNumber(short[] integetpart, short[] fractionpart) {
                 object lobj = new object();
                 lock(lobj) {
                     this.IntegerPart = new List<short>(integetpart);
                     this.FractionPart = new List<short>(fractionpart);

                     this.ReserveLength = 20;
                 }

            }


            /// <summary>
            /// 通过一个int类型的对象实例化一个BigNumber对象
            /// </summary>
            /// <param name="bignumber">一个int类型的对象</param>
            /// <returns>返回一个BigNumber对象</returns>
            public static BigNumber Instance(int bignumber) {
                return new BigNumber(bignumber.ToString());
            }

            /// <summary>
            /// 通过一个long类型的对象实例化一个BigNumber对象
            /// </summary>
            /// <param name="bignumber">一个long类型的对象</param>
            /// <returns>返回一个BigNumber对象</returns>
            public static BigNumber Instance(long bignumber) {
                return new BigNumber(bignumber.ToString());

            }
            /// <summary>
            /// 通过一个double类型的对象实例化一个BigNumber对象
            /// </summary>
            /// <param name="bignumber">一个double类型的对象</param>
            /// <returns>返回一个BigNumber对象</returns>
            public static BigNumber Instance(double bignumber) {
                return new BigNumber(bignumber.ToString());

            }

            /// <summary>
            /// 通过一个decimal类型的对象实例化一个BigNumber对象
            /// </summary>
            /// <param name="bignumber">一个decimal类型的对象</param>
            /// <returns>返回一个BigNumber对象</returns>
            public static BigNumber Instance(decimal bignumber) {

                return new BigNumber(bignumber.ToString());

            }


            #region 摘要
            //乘是连续相加的和
            //除是连续相减的差
            #endregion

 

            public static BigNumber operator +(BigNumber leftValue, BigNumber rightValue) {
                List<short> _fraction = new List<short>();//小数 ->从最后的元素累计相加 然后

反转该数组
                List<short> _integer = new List<short>();//整数
                short _c = 0;//进位的值
                object lobj = new object();
                lock(lobj) {
                    # region 正正 负负

                    if(
                        leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] ==
                        rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1]) {


                        #region 小数部分
                        //同位部分相加,余出部分填充
                        //是否有小数部分
                        int _l = leftValue.FRACTIONpart.Length; //设置操作数小数部分的数组长


                        if(leftValue.FRACTIONpart[0] != (short)

NumberCheck.NonFloatingPointFlag
                            || rightValue.FRACTIONpart[0] != (short)

NumberCheck.NonFloatingPointFlag) {

                            if(leftValue.FRACTIONpart.Length >

rightValue.FRACTIONpart.Length) {

                                for(int i = leftValue.FRACTIONpart.Length - 1; i >

rightValue.FRACTIONpart.Length - 1; i--)
                                    _fraction.Add(leftValue.FRACTIONpart[i]);
                                _l = rightValue.FRACTIONpart.Length;

                            } else if(leftValue.FRACTIONpart.Length <

rightValue.FRACTIONpart.Length) {

                                for(int i = rightValue.FRACTIONpart.Length - 1; i >

leftValue.FRACTIONpart.Length - 1; i--) {

                                    _fraction.Add(rightValue.FRACTIONpart[i]);
                                }
                                _l = leftValue.FRACTIONpart.Length;//获取较短的数组长度
                            }//a._l==1  b._l左右操作数的长度相等

                            //从最后的操作数相加

                            int _t = 0;
                            //ARRAY[0]为校检位,不必相加
                            for(int i = _l - 1; i >= 1; i--) {


                                _t = leftValue.FRACTIONpart[i] + rightValue.FRACTIONpart[i]

+ _c;
                                if(_t >= 10000) {
                                    _fraction.Add((short)(_t % 10000));
                                    _c = (short)(_t / 10000);
                                } else {
                                    _fraction.Add((short)_t);
                                    _c = 0;

                                }

                            }
                            _fraction.Add((short)NumberCheck.FloatingPointFlag);
                            //需反转

                            /*
                            List<short> tflist = new List<short>(_fraction);
                            int _midvalue = 0;
                            for(int i = 0; i < _fraction.Count; i++) {
                                _fraction[i]=tflist[tflist.count

                            }
                         */

                            _fraction.Reverse();
                        } else
                            _fraction.Add((short)NumberCheck.NonFloatingPointFlag);

                        #endregion 小数部分


                        #region 整数部分


                        int _it = 0;

                        int _ic = 0;
                        if(leftValue.INTERGETpart.Length >= rightValue.INTERGETpart.Length)
                            _ic = rightValue.INTERGETpart.Length - 1;//校检位

                        else
                            if(leftValue.INTERGETpart.Length <

rightValue.INTERGETpart.Length)
                                _ic = leftValue.INTERGETpart.Length - 1;


                        //   Console.WriteLine(rightValue.INTERGETpart

[rightValue.INTERGETpart.Length-1]);

                        for(int i = 0; i < _ic; i++) {
                            _it = leftValue.INTERGETpart[i] + rightValue.INTERGETpart[i] +

_c;
                            if(_it >= 10000) {
                                _integer.Add(
                                    Convert.ToInt16(
                                    _it % 10000)
                                );
                                _c = (short)(_it / 10000);
                            } else {
                                _integer.Add(
                                    Convert.ToInt16(
                                    _it));
                                _c = 0;
                            }

                        }


                        if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
                            for(int i = _ic; i < leftValue.INTERGETpart.Length - 1; i++) {
                                _it = leftValue.INTERGETpart[i] + _c;
                                if(_it >= 10000) {
                                    _integer.Add((short)(_it % 10000));
                                    _c = (short)(_it / 10000);
                                } else {
                                    _integer.Add((short)_it);
                                    _c = 0;
                                }


                            } else
                            if(leftValue.INTERGETpart.Length <

rightValue.INTERGETpart.Length)
                                for(int i = _ic; i < rightValue.INTERGETpart.Length - 1;

i++) {
                                    _it = rightValue.INTERGETpart[i] + _c;
                                    if(_it >= 10000) {
                                        _integer.Add((short)(_it % 10000));
                                        _c = (short)(_it / 1000);
                                    } else {
                                        _integer.Add((short)_it);
                                        _c = 0;
                                    }


                                }
                        if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] ==

(short)NumberCheck.Positive)
                            _integer.Add((short)NumberCheck.Positive);
                        else
                            _integer.Add((short)NumberCheck.Negative);


                        return new BigNumber(_integer.ToArray(), _fraction.ToArray());
                    }

                        # endregion 整数部分

 

 


                    #endregion 正正 负负

 

 

                    #region 正负
                    BigNumber _ll = new BigNumber(leftValue.INTERGETpart,

leftValue.FRACTIONpart);
                    BigNumber _rr = new BigNumber(rightValue.INTERGETpart,

rightValue.FRACTIONpart);
                    _ll.IntegerPart[_ll.IntegerPart.Count - 1] = (short)

NumberCheck.Positive;
                    _rr.IntegerPart[_rr.IntegerPart.Count - 1] = (short)

NumberCheck.Positive;
                    BigNumber _rt = _ll - _rr;

                    if(_ll > _rr)
                        _rt.IntegerPart[_rt.IntegerPart.Count - 1] = leftValue.IntegerPart
                    [leftValue.IntegerPart.Count - 1];
                    else
                        if(_ll < _rr)
                            _rt.IntegerPart[_rt.IntegerPart.Count - 1] =

rightValue.IntegerPart
                   [rightValue.IntegerPart.Count - 1];


                    return _rt;
                    #endregion 正负
                }
            }

 

  //operator-最终都是大数减去小数

            public static BigNumber operator -(BigNumber leftValue, BigNumber rightValue) {
                if(BigNumber.OffInvalidZero(leftValue) == BigNumber.OffInvalidZero

(rightValue))
                    return new BigNumber("0");

                BigNumber _rt = BigNumber.zero;
                BigNumber _l = new BigNumber(leftValue.INTERGETpart,

leftValue.FRACTIONpart);
                BigNumber _r = new BigNumber(rightValue.INTERGETpart,

rightValue.FRACTIONpart)
                    ;


                // - -
                if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)

NumberCheck.Negative
                    && rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)

NumberCheck.Negative) {

                    _l.IntegerPart[_l.IntegerPart.Count - 1] = _r.IntegerPart
                    [_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;

                    _rt = subtract(_l, _r);
                    _rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)

NumberCheck.Negative;

                    return _rt;
                }
                // + +
                if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)

NumberCheck.Positive
                    && rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)

NumberCheck.Positive) {

                    _rt = subtract(_l, _r);
                    if(leftValue > rightValue)
                        _rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)

NumberCheck.Positive;
                    else
                        if(leftValue < rightValue)
                            _rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)

NumberCheck.Negative;

                    return _rt;

                }

                // +-
                if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)

NumberCheck.Positive
                    && rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)

NumberCheck.Negative) {

                    _l.IntegerPart[_l.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
                    _r.IntegerPart[_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
                    _rt = _l + _r;

                    return _rt;

                }
                // - +
                if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)

NumberCheck.Negative
                    && rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)

NumberCheck.Positive) {


                    _l.IntegerPart[_l.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
                    _r.IntegerPart[_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;

                    _rt = _l + _r;
                    _rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)

NumberCheck.Negative;
                }
                return _rt;
            }

            //减
            internal static BigNumber subtract(BigNumber theGreatNum, BigNumber theLessNum)

{
                //防止被修改值


                //校检两个数的大小
                BigNumber temp = theLessNum;

                if(theGreatNum < theLessNum) {
                    temp = theGreatNum;
                    theGreatNum = theLessNum;
                    theLessNum = temp;

                }


                List<short> _integer = new List<short>();//整数
                List<short> _fraction = new List<short>();//小数

                //从大数的高位借的值---小数部分的
                //   short _loan = 0;
                int _f_location = theLessNum.FractionPart.Count - 1;//小数部分被借出的数的索

引的起始位置
                int _loanStartl = -1;

                short _NextLoan = 0;//向下一个数借1

                #region 小数部分
                //采用 FractionPart可修改参数值
                if(theGreatNum.FractionPart[0] == (short)NumberCheck.FloatingPointFlag
                    || theGreatNum.FractionPart[0] == (short)NumberCheck.FloatingPointFlag
                    ) {
                    if(theGreatNum.FractionPart[0] == (short)

NumberCheck.NonFloatingPointFlag)
                        theGreatNum.FractionPart[0] = (short)NumberCheck.FloatingPointFlag;
                    //计算小数部分多出来的位
                    int _frc = Math.Abs(theGreatNum.FractionPart.Count -

theLessNum.FractionPart.Count);


                    //如果小于则添加10000(最后)9999。。。。。
                    //如果大于则用原来的大数的小数部分填充到_fraction 需反转
                    if(theGreatNum.FractionPart.Count < theLessNum.FractionPart.Count) {
                        _loanStartl = theGreatNum.FractionPart.Count - 1;//从这个位置减去1 <

标记>
                        while(_frc-- >= 2) {
                            theGreatNum.FractionPart.Add(9999);
                            //  Console.WriteLine("ppp");
                        }
                        theGreatNum.FractionPart.Add(10000);
                        //   _loan = 1;//借的数 需被减


                    } else
                        if(theGreatNum.FractionPart.Count > theLessNum.FractionPart.Count) {
                            int _l = theGreatNum.FractionPart.Count - 1;
                            while(_frc-- >= 1) {
                                _fraction.Add(theGreatNum.FractionPart[_l--]);//填充

                            }

                        }

                    //-------------------------------------------------------计算部分
                    //到索引[1]时停止,因为[0]是校检位

                    while(_f_location >= 1) {
                        if(_f_location == _loanStartl)
                            theGreatNum.FractionPart[_f_location] -= 1;

                        theGreatNum.FractionPart[_f_location] -= _NextLoan;

                        if(theGreatNum.FractionPart[_f_location]
                            < theLessNum.FractionPart[_f_location]
                            ) {
                            theGreatNum.FractionPart[_f_location] += 10000;
                            _NextLoan = 1;
                        }
                        _fraction.Add(
                            Convert.ToInt16(
                            theGreatNum.FractionPart[_f_location] - theLessNum.FractionPart

[_f_location]
                         ));
                        --_f_location;

                    }
                    _fraction.Add((short)NumberCheck.FloatingPointFlag);

                    _fraction.Reverse();//反转

                } else
                    _fraction.Add((short)NumberCheck.NonFloatingPointFlag);

                #endregion 小数部分
                #region 整数部分
                //从个位开始对齐
                //大的数的整数长度不是跟小的数的整数长度相等就是比它大
                //按小的数的整数的长度为基准

 

                int _il = theLessNum.IntegerPart.Count - 1;//小的数的校检位
                for(int i = 0; i < _il; i++) {
                    theLessNum.IntegerPart[i] += _NextLoan;
                    _NextLoan = 0;
                    if(theGreatNum.IntegerPart[i] < theLessNum.IntegerPart[i]) {
                        theGreatNum.IntegerPart[i] += 10000;
                        _NextLoan = 1;
                    }
                    _integer.Add(
                        Convert.ToInt16(
                        theGreatNum.IntegerPart[i] - theLessNum.IntegerPart[i]
                    )
                    );

                }

                int _superfluous = theGreatNum.IntegerPart.Count -

theLessNum.IntegerPart.Count;
                int _LastLoan = _NextLoan;
                if(_superfluous > 0) {
                    for(int i = theLessNum.IntegerPart.Count - 1; i <

theGreatNum.IntegerPart.Count - 1; i++) {
                        if(theGreatNum.IntegerPart[i] < _LastLoan) {
                            theGreatNum.IntegerPart[i] += 10000;
                            _NextLoan = 1;
                        } else
                            _NextLoan = 0;

                        _integer.Add(
                            Convert.ToInt16(
                            theGreatNum.IntegerPart[i] - _LastLoan)
                        );
                        _LastLoan = _NextLoan;

                    }
                }
                int index = _integer.Count - 1;

                while(index > 0) {

                    if(_integer[index] != 0)
                        break;
                    else
                        if(_integer[index] == 0) {
                            _integer.RemoveAt(index);
                            index = _integer.Count - 1;
                        }

                }
                _integer.Add(-5);//未标记
                /*    for(int i = 1; i < _integer.Count - 1; i++) {
                        if(_integer[i] != 0)
                            break;
                        else
                            if(_integer[i] == 0)
                                _integer.RemoveAt(i);


                    }*/


                #endregion 整数部分

                return new BigNumber(_integer.ToArray(), _fraction.ToArray());
            }


 // < >如果碰到相等的 都返回false
            public static bool operator >(BigNumber leftValue, BigNumber rightValue) {
                #region 原有算法
                /*    leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));

            rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));
           // "123456.00000000">"123456"------???????????????????

 

            short leftIntLastV = leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1];
            short rightIntLastV = rightValue.INTERGETpart[rightValue.INTERGETpart.Length -

1];
             //比较校检位,正负数比较
            if(leftIntLastV > rightIntLastV)
                return true;
            else
                if(leftIntLastV < rightIntLastV)
                    return false;

            //同时是整数或负数
            if(leftIntLastV == rightIntLastV) {
             
                //都是正数
                if(leftIntLastV == (short)NumberCheck.Positive) {
                    if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
                        return true;
                    else
                        if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
                            return false;
                }
                    //都是负数
                    if(leftIntLastV == (short)NumberCheck.Negative) {
                        if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
                            return false;
                        else
                            if(leftValue.INTERGETpart.Length <

rightValue.INTERGETpart.Length)
                                return true;


                    }
           

                    int r = string.Compare(leftValue.ReadableBigNumber,

rightValue.ReadableBigNumber);

                //正数
                    if(leftIntLastV == (short)NumberCheck.Positive) {
                        switch(r) {
                            case 1:
                            return true;
                            default:
                            return false;
                        }
                    }else
                        if(leftIntLastV == (short)NumberCheck.Negative) {
                            switch(r) {
                                case -1:
                                return true;
                                default:
                                return false;
                            }

                        }
                  
            }


            return false;
            */
                #endregion 原有算法

                if(leftValue == rightValue)
                    return false;
                return !(leftValue < rightValue);

 

            }
            public static bool operator <(BigNumber _leftValue, BigNumber _rightValue) {
                BigNumber leftValue = new BigNumber(BigNumber.OffInvalidZero(_leftValue));

                BigNumber rightValue = new BigNumber(BigNumber.OffInvalidZero(_rightValue));

                short leftIntLastV = leftValue.INTERGETpart[leftValue.INTERGETpart.Length -

1];
                short rightIntLastV = rightValue.INTERGETpart[rightValue.INTERGETpart.Length

- 1];
                //比较校检位,正负数比较
                if(leftIntLastV > rightIntLastV)
                    return false;
                else
                    if(leftIntLastV < rightIntLastV)
                        return true;

                //同时是整数或负数
                if(leftIntLastV == rightIntLastV) {

                    //都是正数
                    if(leftIntLastV == (short)NumberCheck.Positive) {

                        if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
                            return false;
                        //else
                        if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
                            return true;

                        //整数部分比较
                        //条件是整数部分的数组长度相等
                        //leftValue.INTERGETpart.Length - 2最大的4位,0终止
                        for(int i = leftValue.INTERGETpart.Length - 2; i >= 0; i--) {

                            if(leftValue.INTERGETpart[i] < rightValue.INTERGETpart[i])
                                return true;
                            else
                                if(leftValue.INTERGETpart[i] > rightValue.INTERGETpart[i])
                                    return false;


                        }

                        //小数部分比较 依据整数部分,如果整数部分都是相等的时候,比较小数部

 

 

                    }
                    //都是负数
                    if(leftIntLastV == (short)NumberCheck.Negative) {

                        if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
                            return true;
                        //  else
                        if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
                            return false;
                        //跟正数相反的条件
                        for(int i = leftValue.INTERGETpart.Length - 2; i >= 0; i--) {
                            if(leftValue.INTERGETpart[i] < rightValue.INTERGETpart[i])
                                return false;
                            else
                                if(leftValue.INTERGETpart[i] > rightValue.INTERGETpart[i])
                                    return true;


                        }
                    }

                    //问题所在
                    int r = string.Compare(leftValue.ReadableBigNumber,

rightValue.ReadableBigNumber);

                    //正数
                    if(leftIntLastV == (short)NumberCheck.Positive) {
                        switch(r) {
                            case -1:
                            return true;
                            default:
                            return false;
                        }
                    } else
                        if(leftIntLastV == (short)NumberCheck.Negative) {
                            switch(r) {
                                case 1:
                                return true;
                                default:
                                return false;
                            }

                        }

                }


                return false;

            }

            public static bool operator <=(BigNumber leftValue, BigNumber rightValue) {
                bool ok = false;
                if(leftValue == rightValue)
                    ok = true;
                else
                    if(leftValue < rightValue)
                        ok = true;


                return ok;

            }
            public static bool operator >=(BigNumber leftValue, BigNumber rightValue) {
                bool ok = false;
                if(leftValue == rightValue)
                    ok = true;
                else
                    if(leftValue > rightValue)
                        ok = true;

                return ok;
            }
            public static bool operator ==(BigNumber leftValue, BigNumber rightValue) {

                leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));
                rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));

                if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] !=
                rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1])
                    return false;
                int r = string.Compare(leftValue.ReadableBigNumber,

rightValue.ReadableBigNumber);
                if(r == 0)
                    return true;
                return false;
            }
            public static bool operator !=(BigNumber leftValue, BigNumber rightValue) {
                leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));
                rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));
                if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] !=
                            rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1])
                    return true;
                int r = string.Compare(leftValue.ReadableBigNumber,

rightValue.ReadableBigNumber);
                if(r != 0)
                    return true;
                return false;

            }
            #region ICloneable 成员
            /// <summary>
            /// 克隆BigNumber对象
            /// </summary>
            /// <returns>返回当前实例的深层副本</returns>
            public object Clone() {


                return new BigNumber(
                     this.ReadableBigNumber);
            }

            #endregion

 


//转化运算符
            /// <summary>
            /// 将int类型隐式转换成BigNumber类型,这样一个BigNumber对象能直接与一个int对象进

行运算.
            /// 如BigNumber a =new BigNumber("88");int b=56;BigNumber c= a%b;
            /// 这说明,隐式转化好过显式转化,直接一点
            /// </summary>
            public static implicit operator BigNumber(int convertValue) {

                return new BigNumber(convertValue.ToString());
            }
            //转化运算符
            /// <summary>
            /// 将long类型隐式转换成BigNumber类型
            /// </summary>
            public static implicit operator BigNumber(long convertValue) {

                return new BigNumber
                (convertValue.ToString());
            }
            //转化运算符
            /// <summary>
            /// 将double类型隐式转换成BigNumber类型
            /// </summary>
            public static implicit operator BigNumber(double convertValue) {

                return new BigNumber(convertValue.ToString());
            }
            //转化运算符
            /// <summary>
            /// 将decimal类型隐式转换成BigNumber类型
            /// </summary>
            public static implicit operator BigNumber(decimal convertValue) {
                return new BigNumber(convertValue.ToString());
            }

 

        };//BigNumber

 

 

 

}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值