自然数串类
예제 #1
0
 /// <summary>
 /// 求两个数的最小公倍数。如果其中有个数为0,则返回0
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static NaturalNumStr LeastCommonMultiple(NaturalNumStr a, NaturalNumStr b)
 {
     if (a == null || b == null)
     {
         throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue);
     }
     //统一计算空间
     if (a.Space != b.Space)
     {
         if (a.Space == OperationSpace.DefaultSpace)
         {
             a = (NaturalNumStr)a.ChangeOperationSpace(b.Space);
         }
         else if (b.Space == OperationSpace.DefaultSpace)
         {
             b = (NaturalNumStr)b.ChangeOperationSpace(a.Space);
         }
         else
         {
             throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace);
         }
     }
     if (a == 0 || b == 0)
     {
         return(new NaturalNumStr(0, a.Space));
     }
     return(a * b / GreatestCommonDivisor(a, b));
 }
예제 #2
0
        /// <summary>
        /// 取模
        /// </summary>
        /// <param name="a">被模数</param>
        /// <param name="b">模数</param>
        /// <returns>包含余数和商的元组</returns>
        public static (NaturalNumStr, NaturalNumStr) Mod(NaturalNumStr a, NaturalNumStr b)
        {
            var ans     = a.Mod_unsigned(b, 0);
            var new_ans = (new NaturalNumStr(ans.Item1 as NumStr, false), new NaturalNumStr(ans.Item2 as NumStr, false));

            new_ans.Item1.PositiveOrNegative = new_ans.Item1.IsEmpty() ? 0 : 1;
            new_ans.Item2.PositiveOrNegative = new_ans.Item2.IsEmpty() ? 0 : 1;
            return(new_ans);
        }
예제 #3
0
        /// <summary>
        /// 输出将该数去掉小数点以后的数
        /// </summary>
        /// <returns></returns>
        public NaturalNumStr RemoveDecimalPoint()
        {
            var n = new NaturalNumStr(0, Space);

            if (IsZero)
            {
                return(n);
            }
            else
            {
                n.integerNumList     = new LinkedList <uint>();
                n.PositiveOrNegative = 1;
            }

            if (decimalNumList != null)
            {
                if (integerNumList == null)
                {
                    var i = decimalNumList.GetEnumerator();
                    //跳过高位0
                    do
                    {
                        i.MoveNext();
                    }while (i.Current == 0);
                    do
                    {
                        n.integerNumList.AddFirst(i.Current);
                    }while (i.MoveNext());
                    return(n);
                }
                else
                {
                    foreach (var i in decimalNumList)
                    {
                        n.integerNumList.AddFirst(i);
                    }
                }
            }
            if (integerNumList != null)
            {
                foreach (var i in integerNumList)
                {
                    n.integerNumList.AddLast(i);
                }
            }
            return(n);
        }
예제 #4
0
        /// <summary>
        /// 求两个数的最大公约数。如果其中一个数为0、另一个不为0,则返回不为0的那个数
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static NaturalNumStr GreatestCommonDivisor(NaturalNumStr a, NaturalNumStr b)
        {
            if (a == null || b == null)
            {
                throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue);
            }
            var old_a = a;
            var old_b = b;

            //统一计算空间
            if (a.Space != b.Space)
            {
                if (a.Space == OperationSpace.DefaultSpace)
                {
                    a = (NaturalNumStr)a.ChangeOperationSpace(b.Space);
                }
                else if (b.Space == OperationSpace.DefaultSpace)
                {
                    b = (NaturalNumStr)b.ChangeOperationSpace(a.Space);
                }
                else
                {
                    throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace);
                }
            }
            if (a == 0)
            {
                if (b == 0)
                {
                    throw new IllegalOperationException();
                }
                else
                {
                    if (ReferenceEquals(b, old_b))
                    {
                        return(new NaturalNumStr(b));
                    }
                    else
                    {
                        return(b);
                    }
                }
            }
            else if (b == 0)
            {
                if (ReferenceEquals(a, old_a))
                {
                    return(new NaturalNumStr(a));
                }
                else
                {
                    return(a);
                }
            }
            if (b > a)
            {
                var t = a;
                a = b;
                b = t;
            }
            //辗转相除法
            while (!b.IsZero)
            {
                var t = a;
                a = b;
                b = t % b;
            }
            if (ReferenceEquals(a, old_a) || ReferenceEquals(a, old_b))
            {
                return(new NaturalNumStr(a));
            }
            else
            {
                return(a);
            }
        }
예제 #5
0
        /// <summary>
        /// 开平方运算
        /// </summary>
        /// <param name="maxDecimalPlaces">答案保留小数位数</param>
        /// <returns></returns>
        protected override Digitable Sqrt(int maxDecimalPlaces)
        {
            NumStr a = new NumStr(this);

            if (a == null)
            {
                throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue);
            }
            //特殊情况
            if (a.IsNegative)
            {
                throw new IllegalOperationException();
            }
            else if (a.IsZero)
            {
                return(new NumStr(0, a.Space, maxDecimalPlaces));
            }

            //设进制为k,先将数字多次放大或缩小k^2倍,使其归一化为:1<=a<=k^2
            var one        = new NaturalNumStr(1, a.Space);
            var k2         = new NaturalNumStr(a.Space.NumberBase * a.Space.NumberBase, a.Space);
            var shiftTimes = 0;

            while (a < one)
            {
                a.RightShift(2);
                shiftTimes++;
            }
            while (a > k2)
            {
                a.LeftShift(2);
                shiftTimes--;
            }

            //平方根初值x
            var x = new NumStr(0, a.Space);
            //x当前的有效数字位数
            var nx = 0;
            //x^2初值
            var x2 = new NumStr(0, a.Space);
            //(x+1)^2的值
            NumStr x12;

            do
            {
                //用完全平方公式计算(y+1)^2
                x12 = x2 + x + x + one;
                if (a < x12)
                {
                    //本位枚举完成,开始枚举下一位
                    x.RightShift(1);  //x=x*k
                    nx++;
                    x2.RightShift(2); //x2=x2*k^2
                    a.RightShift(2);  //a=a*k^2
                }
                else
                {
                    //继续枚举
                    x  = x + one;
                    x2 = x12;
                }
            } while (nx < maxDecimalPlaces + 1 - shiftTimes && a != x12);
            x.LeftShift(x.IntegerPlaces + x.DecimalPlaces - 1 + shiftTimes);
            return(x);
        }