Beispiel #1
0
        /// <summary>开方</summary>
        static internal BigNumber Sqrt(BigNumber value, int precision)
        {
            if (!value.IsPlus)
            {
                throw new ExpressionException("只有正数才有开平方运算");
            }

            List <int> div            = new List <int>();
            int        index          = 0;
            int        resultIntCount = (value.IntPart.Count + 1) / 2;

            List <int> result = GetFirstDiv(value, ref div, ref index);

            div = FirstTry(result, div);
            div.AddRange(GetNewTwoDiv(value, ref index));
            BigCalculate.RemoveStartZero(div);
            //考虑精度的计算
            while (true)
            {
                div = TryDiv(div, result);
                if (result.Count - resultIntCount >= precision)
                {
                    break;
                }

                div.AddRange(GetNewTwoDiv(value, ref index));
                BigCalculate.RemoveStartZero(div);
            }

            return(new BigNumber(result.GetRange(0, resultIntCount), result.GetRange(resultIntCount, result.Count - resultIntCount), true));
        }
Beispiel #2
0
        /// <summary>第一次用开方尝试</summary>
        private static List <int> FirstTry(List <int> result, List <int> div)
        {
            int tryDiv = BigNumber.Max / 2;
            int low    = 1;
            int top    = BigNumber.Max - 1;

            //第一位数是1

            //第一用平方试商
            while (true)
            {
                if (BigCalculate.CompareList(new List <int>()
                {
                    1
                }, div) == 0)
                {
                    div = BigCalculate.IntMinus(div, new List <int>()
                    {
                        1
                    });
                    result.Add(1);
                    break;
                }
                //连9都小了,那么就是9
                if (BigCalculate.CompareList(BigCalculate.Multiply(BigNumber.Max - 1, BigNumber.Max - 1), div) == -1)
                {
                    div = BigCalculate.IntMinus(div, BigCalculate.Multiply(BigNumber.Max - 1, BigNumber.Max - 1));
                    result.Add(BigNumber.Max - 1);
                    break;
                }
                int c = BigCalculate.CompareList(BigCalculate.Multiply(tryDiv, tryDiv), div);
                //商大了
                if (c == -1)
                {
                    low    = tryDiv;
                    tryDiv = (low + top) / 2;
                }
                else if (c == 1)     //商小了
                {
                    top    = tryDiv;
                    tryDiv = (low + top) / 2;
                }
                else     //刚好相等
                {
                    div.Clear();
                    result.Add(tryDiv);
                    break;
                }

                if (low + 1 == top)
                {
                    div = BigCalculate.IntMinus(div, BigCalculate.Multiply(low, low));
                    result.Add(low);
                    break;
                }
            }
            return(div);
        }
Beispiel #3
0
        /// <summary>执行一次试商的运算</summary>
        /// <param name="div">已经加组的被除数</param>
        /// <param name="result">已生成的结果</param>
        static List <int> TryDiv(List <int> div, List <int> result)
        {
            int i   = BigNumber.Max / 2;
            int low = 0;
            int top = BigNumber.Max - 1;

            //连1都大了,那么商为0,除数不变
            if (CompartDiv(1, result, div) == 1)
            {
                result.Add(0);
                return(div);
            }
            //连9999都小了
            if (CompartDiv(BigNumber.Max - 1, result, div) == -1)
            {
                List <int> r = BigCalculate.IntMinus(div, CalDiv(BigNumber.Max - 1, result));
                result.Add(BigNumber.Max - 1);
                return(r);
            }

            while (true)
            {
                int c = CompartDiv(i, result, div);
                //商大了
                if (c == 1)
                {
                    top = i;
                    i   = (low + top) / 2;
                }
                //商小了
                else if (c == -1)
                {
                    low = i;
                    i   = (low + top) / 2;
                }
                //刚好相等
                else
                {
                    //div.Clear();
                    result.Add(i);
                    return(new List <int>());
                }
                //已找到合适的商
                if (low + 1 == top)
                {
                    List <int> r = BigCalculate.IntMinus(div, CalDiv(low, result));
                    result.Add(low);
                    return(r);
                }
            }
        }
Beispiel #4
0
        /// <summary>计算x(x+20*result)的值</summary>
        static List <int> CalDiv(int x, List <int> result)
        {
            List <int> result20 = BigCalculate.Multiply(new List <int>()
            {
                BigNumber.Max * 2
            }, result);
            List <int> add = BigCalculate.IntAdd(new List <int>()
            {
                x
            }, result20, 0);
            List <int> r = BigCalculate.Multiply(new List <int>()
            {
                x
            }, add);

            return(r);
        }
Beispiel #5
0
 /// <summary>返回0.00001这样的数小数点后、有效数前有几个零</summary>
 internal int GetPrecision(int value)
 {
     if (value == 0)
     {
         BigCalculate.RemoveStartZero(IntPart);
         if (IntPart.Count == 1 && IntPart[0] == 0)
         {
             if (DecimalPart.Count == 0)
             {
                 return(0);
             }
             for (int i = 0; i < DecimalPart.Count; i++)
             {
                 if (DecimalPart[i] != 0)
                 {
                     return(i);
                 }
             }
             return(DecimalPart.Count);
         }
         return(0);
     }
     else
     {
         if (IntPart.Count == 1 && IntPart[0] == 1)
         {
             if (DecimalPart.Count == 0)
             {
                 return(0);
             }
             for (int i = 0; i < DecimalPart.Count; i++)
             {
                 if (DecimalPart[i] != 0)
                 {
                     return(i);
                 }
             }
             return(DecimalPart.Count);
         }
         return(0);
     }
 }
        /// <summary>识别出一个大数,返回值为这个是不是正数</summary>
        public static bool GetBigNumber(string text, List <int> intPart, List <int> decimalPart)
        {
            ValidateNumber(text);
            bool isPlus  = true;
            int  haveSym = 0;

            if (text[0] == '-')
            {
                isPlus  = false;
                haveSym = 1;
            }
            else if (text[0] == '+')
            {
                haveSym = 1;
            }
            int pointIndex = text.IndexOf('.');

            //有小数点
            if (pointIndex != -1)
            {
                int i = 0;
                if ((pointIndex - haveSym) % BigNumber.OneCount != 0)
                {
                    intPart.Add(Convert.ToInt32(text.Substring(haveSym, (pointIndex - haveSym) % BigNumber.OneCount)));
                }
                for (; i < (pointIndex - haveSym) / BigNumber.OneCount; i++)
                {
                    intPart.Add(Convert.ToInt32(text.Substring(haveSym + i * BigNumber.OneCount + (pointIndex - haveSym) % BigNumber.OneCount, BigNumber.OneCount)));
                }
                i = pointIndex + 1;
                while (i < text.Length)
                {
                    if (text.Length - i >= BigNumber.OneCount)
                    {
                        decimalPart.Add(Convert.ToInt32(text.Substring(i, BigNumber.OneCount)));
                    }
                    else
                    {
                        decimalPart.Add(Convert.ToInt32(text.Substring(i, (text.Length - i) % BigNumber.OneCount).PadRight(BigNumber.OneCount, '0')));
                    }
                    i += BigNumber.OneCount;
                }
            }
            //没有小数点
            else
            {
                if ((text.Length - haveSym) % BigNumber.OneCount != 0)
                {
                    intPart.Add(Convert.ToInt32(text.Substring(haveSym, (text.Length - haveSym) % BigNumber.OneCount)));
                }
                for (int i = 0; i < (text.Length - haveSym) / BigNumber.OneCount; i++)
                {
                    intPart.Add(Convert.ToInt32(text.Substring(haveSym + i * BigNumber.OneCount + (text.Length - haveSym) % BigNumber.OneCount, BigNumber.OneCount)));
                }
            }
            BigCalculate.RemoveStartZero(intPart);
            if (intPart.Count == 0)
            {
                intPart.Add(0);
            }
            return(isPlus);
        }
Beispiel #7
0
 /// <summary>对除数进行比较</summary>
 static int CompartDiv(int x, List <int> result, List <int> div)
 {
     return(BigCalculate.CompareList(CalDiv(x, result), div));
 }
Beispiel #8
0
 /// <summary>指定精确的除法</summary>
 public static BigNumber Division(BigNumber dividend, BigNumber divisor, int precision)
 {
     return(BigCalculate.Division(dividend, divisor, precision));
 }
Beispiel #9
0
 public static BigNumber operator /(BigNumber a, BigNumber b)
 {
     return(BigCalculate.Division(a, b));
 }
Beispiel #10
0
 public static BigNumber operator *(BigNumber a, BigNumber b)
 {
     return(BigCalculate.Multiply(a, b));
 }
Beispiel #11
0
 public static BigNumber operator -(BigNumber a, BigNumber b)
 {
     return(BigCalculate.Minus(a, b));
 }
Beispiel #12
0
 public static BigNumber operator +(BigNumber a, BigNumber b)
 {
     return(BigCalculate.Add(a, b));
 }
Beispiel #13
0
        static int ComparePlus(BigNumber one, BigNumber two)
        {
            BigCalculate.RemoveStartZero(one.IntPart);
            BigCalculate.RemoveStartZero(two.IntPart);
            int minDecimalLength = one.DecimalPart.Count < two.DecimalPart.Count ? one.DecimalPart.Count : two.DecimalPart.Count;

            //通过正数的长短比较
            if (one.IntPart.Count > two.IntPart.Count)
            {
                return(1);
            }
            else if (one.IntPart.Count < two.IntPart.Count)
            {
                return(-1);
            }
            else
            {
                //从最高位依次比较
                for (int i = 0; i < one.IntPart.Count; i++)
                {
                    if (one.IntPart[i] > two.IntPart[i])
                    {
                        return(1);
                    }
                    else if (one.IntPart[i] < two.IntPart[i])
                    {
                        return(-1);
                    }
                }
                //比较小数部分,行判断是否有小数位
                if (one.DecimalPart.Count == 0 && two.DecimalPart.Count != 0)
                {
                    return(-1);
                }
                else if (one.DecimalPart.Count != 0 && two.DecimalPart.Count == 0)
                {
                    return(1);
                }
                else if (one.DecimalPart.Count == 0 && two.DecimalPart.Count == 0)
                {
                    return(0);
                }
                else
                {
                    for (int i = 0; i < minDecimalLength; i++)
                    {
                        if (one.DecimalPart[i] > two.DecimalPart[i])
                        {
                            return(1);
                        }
                        else if (one.DecimalPart[i] < two.DecimalPart[i])
                        {
                            return(-1);
                        }
                    }
                    if (one.DecimalPart.Count > two.DecimalPart.Count)
                    {
                        return(1);
                    }
                    else if (one.DecimalPart.Count < two.DecimalPart.Count)
                    {
                        return(-1);
                    }
                }
                return(0);
            }
        }