长数据类

public class LongNumber
        {
            public enum NumberFlag
            {
                /// <summary>
                ///  负数
                /// </summary>
                Negative,

                /// <summary>
                /// 正数
                /// </summary>
                Positive
            }

            public NumberFlag Flag { get; set; }
            public string Number { get; set; }

            public LongNumber()
            {
                this.Flag = NumberFlag.Positive;
                this.Number = "0";
            }

            public LongNumber(string number)
            {
                if (!LongNumber.CheckNumber(number))
                    throw new InvalidCastException("Input not is a number.");

                this.Flag = NumberFlag.Positive;
                this.Number = number;
            }

            public LongNumber(NumberFlag flag, string number)
            {
                if (!LongNumber.CheckNumber(number))
                    throw new InvalidCastException("Input not is a number.");

                this.Flag = flag;
                this.Number = number;
            }

            public override string ToString()
            {
                if (LongNumber.EqualsZero(this))
                    return "0";
                else
                {
                    return string.Format("{0}{1}", this.Flag == NumberFlag.Positive ? string.Empty : "-", this.Number.TrimStart('0'));
                }
            }

            /// <summary>
            /// 检测给定字符串是否是一个有效的数字
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            public static bool CheckNumber(string a)
            {
                if (string.IsNullOrWhiteSpace(a))
                    return false;

                var content = a;
                foreach (var item in content)
                {
                    if (!"0123456789.".Contains(item))
                    {
                        return false;
                    }
                }
                return true;
            }

            /// <summary>
            /// 检测给定的数字是否等于零
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            public static bool EqualsZero(LongNumber a)
            {
                var pos = a.Number.LastIndexOf('.');
                var left = a.Number;
                var right = string.Empty;
                if (pos >= 0)
                {
                    left = a.Number.Substring(0, pos);
                    right = a.Number.Substring(pos + 1);
                }

                if (left.Any(c => c != '0') || right.Any(c => c != '0'))
                    return false;

                return true;
            }

            public static LongNumber Add(LongNumber a, LongNumber b)
            {
                if (a.Flag == b.Flag)
                    return new LongNumber(a.Flag, AddWithoutFlag(a, b).Number);
                else if (a.Flag == NumberFlag.Negative)
                    return LongNumber.MinusWithoutFlag(b, new LongNumber(NumberFlag.Positive, a.Number));
                else
                    return LongNumber.MinusWithoutFlag(a, new LongNumber(NumberFlag.Positive, b.Number));
            }

            /// <summary>
            /// 计算a加b的结果
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            private static LongNumber AddWithoutFlag(LongNumber a, LongNumber b)
            {
                //格式化数据
                var inputA = a.Number;
                var inputB = b.Number;
                FormatNumber(ref inputA, ref inputB);
                a.Number = inputA;
                b.Number = inputB;

                //定义进位值
                var carry = 0;
                var sbResult = new StringBuilder();
                for (var i = a.Number.Length - 1; i >= 0; i--)
                {
                    var tempA = a.Number[i];
                    var tempB = b.Number[i];

                    if (tempA == '.')
                    {
                        sbResult.Insert(0, tempA);
                        continue;
                    }

                    var tempResult = int.Parse(tempA.ToString()) + int.Parse(tempB.ToString()) + carry;
                    if (tempResult > 9)
                    {
                        carry = 1;
                        tempResult -= 10;
                    }
                    else
                    {
                        carry = 0;
                    }
                    sbResult.Insert(0, tempResult.ToString());
                }

                if (carry > 0)
                    sbResult.Insert(0, carry);

                return new LongNumber(sbResult.ToString());
            }

            public static LongNumber Minus(LongNumber a, LongNumber b)
            {
                if (a.Flag == b.Flag)
                {
                    var c = LongNumber.MinusWithoutFlag(new LongNumber(a.Number), new LongNumber(b.Number));
                    if (a.Flag == NumberFlag.Negative)
                        c = new LongNumber(c.Flag == NumberFlag.Positive ? NumberFlag.Negative : NumberFlag.Positive, c.Number);
                    return c;
                }
                else
                {
                    var c = LongNumber.AddWithoutFlag(new LongNumber(a.Number), new LongNumber(b.Number));
                    if (a.Flag == NumberFlag.Negative)
                        c = new LongNumber(c.Flag == NumberFlag.Positive ? NumberFlag.Negative : NumberFlag.Positive, c.Number);
                    return c;
                }
            }

            /// <summary>
            /// 计算a减b的结果
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            private static LongNumber MinusWithoutFlag(LongNumber a, LongNumber b)
            {
                var resultFlag = NumberFlag.Positive;

                if (Compare(a, b) < 0)
                {
                    resultFlag = NumberFlag.Negative;
                    var tempC = a.Number;
                    a.Number = b.Number;
                    b.Number = tempC;
                }

                //格式化数据
                var inputA = a.Number;
                var inputB = b.Number;
                FormatNumber(ref inputA, ref inputB);
                a.Number = inputA;
                b.Number = inputB;

                //定义借位
                var borrow = 0;
                var sbResult = new StringBuilder();
                for (var i = a.Number.Length - 1; i >= 0; i--)
                {
                    var tempA = a.Number[i];
                    var tempB = b.Number[i];

                    if (tempA == '.')
                    {
                        sbResult.Insert(0, tempA);
                        continue;
                    }

                    var tempResult = int.Parse(tempA.ToString()) - int.Parse(tempB.ToString()) - borrow;
                    if (tempResult < 0)
                    {
                        borrow = 1;
                        tempResult += 10;
                    }
                    else
                    {
                        borrow = 0;
                    }
                    sbResult.Insert(0, tempResult.ToString());
                }

                return new LongNumber(resultFlag, sbResult.ToString());
            }

            /// <summary>
            /// 计算a乘以b的结果
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static LongNumber Multiply(LongNumber a, LongNumber b)
            {
                //获取小数位数
                var aDecimalDigits = getDecimalDigits(a.Number);
                var bDecimalDigits = getDecimalDigits(b.Number);

                a.Number = a.Number.Replace(".", string.Empty);
                b.Number = b.Number.Replace(".", string.Empty);

                //用b从右到左的每一位去乘a
                var totalResult = new LongNumber("0");
                for (var i = b.Number.Length - 1; i >= 0; i--)
                {
                    var tempResult = new LongNumber("0");
                    for (var j = 0; j < int.Parse(b.Number[i].ToString()); j++)
                    {
                        tempResult = Add(tempResult, a);
                    }
                    var sb = new StringBuilder();
                    for (var j = 0; j < b.Number.Length - 1 - i; j++)
                    {
                        sb.Append('0');
                    }
                    sb.Insert(0, tempResult.Number);
                    totalResult = Add(totalResult, new LongNumber(sb.ToString()));
                }

                var sbResult = new StringBuilder(totalResult.Number);

                if (aDecimalDigits + bDecimalDigits > 0)
                    sbResult.Insert(sbResult.Length - aDecimalDigits - bDecimalDigits, '.');

                var resultFlag = LongNumber.NumberFlag.Positive;
                if (a.Flag != b.Flag)
                    resultFlag = NumberFlag.Negative;

                return new LongNumber(resultFlag, sbResult.ToString());
            }

            /// <summary>
            /// 计算a除以b的结果,保留maxDecimalDigits位小数
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <param name="maxDecimalDigits"></param>
            /// <returns></returns>
            public static LongNumber Devide(LongNumber a, LongNumber b, int maxDecimalDigits = 2)
            {
                var result = new StringBuilder();
                var numberA = new StringBuilder();

                //按照手动除法的规律去从高到低按位除
                for (var i = 0; i < a.Number.Length; i++)
                {
                    if (a.Number[i] == '.')
                    {
                        if (result.Length == 0)
                            result.Append(0);
                        result.Append('.');
                        continue;
                    }

                    //取被除数下一位
                    numberA.Append(a.Number[i].ToString());
                    var tempA = new LongNumber(numberA.ToString());

                    //如果当前取到的被除数位数与上次结果组合后大于等于除数,则可以除
                    if (Compare(tempA, b) >= 0)
                    {
                        var tempResult = 0;
                        //循环减一次除数,以累积计算当前位的最大商
                        while (Compare(tempA, b) >= 0)
                        {
                            tempResult++;
                            tempA = Minus(tempA, b);
                        }
                        result.Append(tempResult);
                        numberA.Clear();
                        numberA.Append(tempA);
                    }
                    //如果当前取到的被除数位数与上次结果组合后小于除数,则商当前位填0
                    else
                    {
                        result.Append(0);
                    }
                }

                var resultFlag = LongNumber.NumberFlag.Positive;
                if (a.Flag != b.Flag)
                    resultFlag = NumberFlag.Negative;

                return new LongNumber(resultFlag, result.ToString());
            }

            /// <summary>
            /// 计算a的b次方
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static LongNumber Power(LongNumber a, LongNumber b)
            {
                var result = new LongNumber("1");
                var counter = new LongNumber("0");
                while (Compare(counter, b) < 0)
                {
                    result = Multiply(result, new LongNumber(a.Flag, a.Number));
                    counter = Add(counter, new LongNumber("1"));
                }
                return result;
            }

            /// <summary>
            /// 比较两个长整数的大小
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static int Compare(LongNumber a, LongNumber b)
            {
                if (LongNumber.EqualsZero(a) && LongNumber.EqualsZero(b))
                    return 0;

                //格式化数据
                var inputA = a.Number;
                var inputB = b.Number;
                FormatNumber(ref inputA, ref inputB);
                a.Number = inputA;
                b.Number = inputB;

                var flagA = a.Flag;
                var flagB = b.Flag;

                if (!LongNumber.EqualsZero(a))
                    flagA = a.Flag;

                if (!LongNumber.EqualsZero(b))
                    flagB = b.Flag;

                if (flagA > flagB)
                    return 1;
                else if (flagA < flagB)
                    return -1;
                else
                {
                    for (var i = 0; i < a.Number.Length; i++)
                    {
                        var itemA = int.Parse(a.Number[i].ToString());
                        var itemB = int.Parse(b.Number[i].ToString());

                        if (itemA == itemB)
                            continue;

                        if (itemA > itemB)
                            return 1;
                        else
                            return -1;
                    }
                    return 0;
                }
            }

            /// <summary>
            /// 进制转换
            /// </summary>
            /// <param name="num">要转换的数字</param>
            /// <param name="toBase">要转换的进制基数</param>
            /// <returns>转换进制后每一位的数据</returns>
            public static List<LongNumber> BaseCast(LongNumber num, LongNumber toBase)
            {
                if (LongNumber.Compare(toBase, new LongNumber("0")) < 0)
                    throw new InvalidCastException("toBase must be a positive number");

                var result = new List<LongNumber>();
                var temp = new LongNumber(num.Flag, num.Number);
                while (true)
                {
                    var a = LongNumber.Devide(temp, toBase, 0);
                    var b = LongNumber.Multiply(a, toBase);
                    var c = LongNumber.Minus(temp, b);
                    if (LongNumber.Compare(c, new LongNumber("0")) < 0)
                        c = LongNumber.Add(c, toBase);
                    result.Add(c);

                    if (LongNumber.EqualsZero(a))
                        break;

                    temp = a;
                }

                result.Reverse();
                return result;
            }

            /// <summary>
            /// 往小数点后面的小数位末尾补0,在小数左边补零,以使两数左右对齐
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            private static void FormatNumber(ref string a, ref string b)
            {
                //获取小数位数
                var aDecimalDigits = getDecimalDigits(a);
                var bDecimalDigits = getDecimalDigits(b);

                //补齐小数位数,使其右对齐
                var sb = new StringBuilder();
                for (var i = 0; i < Math.Abs(aDecimalDigits - bDecimalDigits); i++)
                {
                    sb.Append('0');
                }
                if (aDecimalDigits > bDecimalDigits)
                {
                    sb.Insert(0, b);
                    b = sb.ToString();
                }
                else if (bDecimalDigits > aDecimalDigits)
                {
                    sb.Insert(0, a);
                    a = sb.ToString();
                }

                //补齐左边位数,使其可以左对齐
                sb.Clear();
                for (var i = 0; i < Math.Abs(a.Length - b.Length); i++)
                {
                    sb.Append('0');
                }

                if (a.Length > b.Length)
                {
                    sb.Append(b);
                    b = sb.ToString();
                }
                else if (b.Length > a.Length)
                {
                    sb.Append(a);
                    a = sb.ToString();
                }
            }

            /// <summary>
            /// 获取小数位数
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            private static int getDecimalDigits(string a)
            {
                return a.IndexOf('.') >= 0 ? a.Length - a.IndexOf('.') - 1 : 0;
            }
        }
原文地址:https://www.cnblogs.com/nanfei/p/10268391.html