Beispiel #1
0
        public BigNumber Neg()
        {
            BigNumber res = 0;

            BigNumber.Neg(this, res);
            return(res);
        }
        static void M_log_basic_iteration(BigNumber nn, BigNumber rr, int places)
        {
            BigNumber tmp0, tmp1, tmp2, tmpX;

            if (places < 360)
            {
                BigNumber.M_log_solve_cubic(nn, rr, places);
            }
            else
            {
                tmp0 = new BigNumber();
                tmp1 = new BigNumber();
                tmp2 = new BigNumber();
                tmpX = new BigNumber();

                BigNumber.M_log_solve_cubic(nn, tmpX, 110);
                BigNumber.Neg(tmpX, tmp0);
                BigNumber.Exp(tmp0, tmp1, (places + 8));
                BigNumber.Mul(tmp1, nn, tmp2);
                BigNumber.Sub(tmp2, BigNumber.One, tmp1);

                BigNumber.M_log_near_1(tmp1, tmp0, (places - 104));

                BigNumber.Add(tmpX, tmp0, tmp1);
                BigNumber.Round(tmp1, rr, places);
            }
        }
Beispiel #3
0
        static void Floor(BigNumber dst, BigNumber src)
        {
            BigNumber.Copy(src, dst);

            if (BigNumber.IsInteger(dst) > 0)
            {
                return;
            }
            if (dst.exponent <= 0)       /* if |bb| < 1, result is -1 or 0 */
            {
                if (dst.signum < 0)
                {
                    BigNumber.Neg(BigNumber.One, dst);
                }
                else
                {
                    BigNumber.SetZero(dst);
                }

                return;
            }

            if (dst.signum < 0)
            {
                BigNumber mtmp = new BigNumber();
                BigNumber.Neg(dst, mtmp);

                mtmp.dataLength = mtmp.exponent;

                BigNumber.Normalize(mtmp);

                BigNumber.Add(mtmp, BigNumber.One, dst);
                dst.signum = -1;
            }
            else
            {
                dst.dataLength = dst.exponent;
                BigNumber.Normalize(dst);
            }
        }
Beispiel #4
0
        static public void Sub(BigNumber src, BigNumber dst, BigNumber result)
        {
            int       itmp, j, ChangeOrderFlag, icompare, aexp, bexp, borrow, adigits, bdigits;
            sbyte     sign;
            BigNumber A = 0, B = 0;

            if (dst.signum == 0)
            {
                BigNumber.Copy(src, result);
                return;
            }

            if (src.signum == 0)
            {
                BigNumber.Copy(dst.Neg(), result);
                return;
            }

            if (src.signum == 1 && dst.signum == -1)
            {
                dst.signum = 1;
                Add(src, dst, result);
                dst.signum = -1;
                return;
            }

            if (src.signum == -1 && dst.signum == 1)
            {
                dst.signum = -1;
                Add(src, dst, result);
                dst.signum = 1;
                return;
            }

            BigNumber.Abs(A, src);
            BigNumber.Abs(B, dst);

            if ((icompare = Compare(A, B)) == 0)
            {
                SetZero(result);
                return;
            }

            if (icompare == 1)  /*  |a| > |b|  (do A-B)  */
            {
                ChangeOrderFlag = 1;
                sign            = src.signum;
            }
            else                /*  |b| > |a|  (do B-A)  */
            {
                ChangeOrderFlag = 0;
                sign            = (sbyte)-(src.signum);
            }

            aexp = A.exponent;
            bexp = B.exponent;

            if (aexp > bexp)
            {
                Scale(B, (aexp - bexp));
            }
            if (aexp < bexp)
            {
                Scale(A, (bexp - aexp));
            }

            adigits = A.dataLength;
            bdigits = B.dataLength;

            if (adigits > bdigits)
            {
                Pad(B, adigits);
            }

            if (adigits < bdigits)
            {
                Pad(A, bdigits);
            }

            if (ChangeOrderFlag == 1)            // |a| > |b|  (do A-B)
            {
                Copy(A, result);

                j = (result.dataLength + 1) >> 1;

                borrow = 0;

                while (true)
                {
                    j--;
                    itmp = ((int)result.mantissa[j] - ((int)B.mantissa[j] + borrow));

                    if (itmp >= 0)
                    {
                        result.mantissa[j] = (byte)itmp;
                        borrow             = 0;
                    }
                    else
                    {
                        result.mantissa[j] = (byte)(100 + itmp);
                        borrow             = 1;
                    }

                    if (j == 0)
                    {
                        break;
                    }
                }
            }
            else                // |b| > |a|  (do B-A) instead
            {
                Copy(B, result);

                j      = (result.dataLength + 1) >> 1;
                borrow = 0;

                while (true)
                {
                    j--;
                    itmp = (int)result.mantissa[j] - ((int)A.mantissa[j] + borrow);

                    if (itmp >= 0)
                    {
                        result.mantissa[j] = (byte)itmp;
                        borrow             = 0;
                    }
                    else
                    {
                        result.mantissa[j] = (byte)(100 + itmp);
                        borrow             = 1;
                    }

                    if (j == 0)
                    {
                        break;
                    }
                }
            }

            result.signum = sign;

            BigNumber.Normalize(result);
        }
Beispiel #5
0
        static void Sqrt(BigNumber src, BigNumber dst, int places)
        {
            int  ii, nexp, tolerance, dplaces;
            bool bflag;

            if (src.signum <= 0)
            {
                if (src.signum == -1)
                {
                    throw new BigNumberException("'Sqrt',Invalid Argument");
                }
            }

            BigNumber last_x = new BigNumber();
            BigNumber guess  = new BigNumber();
            BigNumber tmpN   = new BigNumber();
            BigNumber tmp7   = new BigNumber();
            BigNumber tmp8   = new BigNumber();
            BigNumber tmp9   = new BigNumber();

            BigNumber.Copy(src, tmpN);

            nexp           = src.exponent / 2;
            tmpN.exponent -= 2 * nexp;

            BigNumber.SQrtGuess(tmpN, guess);

            tolerance = places + 4;
            dplaces   = places + 16;
            bflag     = false;

            BigNumber.Neg(BigNumber.Ten, last_x);

            ii = 0;

            while (true)
            {
                BigNumber.Mul(tmpN, guess, tmp9);
                BigNumber.Mul(tmp9, guess, tmp8);
                BigNumber.Round(tmp8, tmp7, dplaces);
                BigNumber.Sub(BigNumber.Three, tmp7, tmp9);
                BigNumber.Mul(tmp9, guess, tmp8);
                BigNumber.Mul(tmp8, BigNumber.BN_OneHalf, tmp9);

                if (bflag)
                {
                    break;
                }

                BigNumber.Round(tmp9, guess, dplaces);

                if (ii != 0)
                {
                    BigNumber.Sub(guess, last_x, tmp7);

                    if (tmp7.signum == 0)
                    {
                        break;
                    }

                    /*
                     *   if we are within a factor of 4 on the error term,
                     *   we will be accurate enough after the *next* iteration
                     *   is complete.  (note that the sign of the exponent on
                     *   the error term will be a negative number).
                     */

                    if ((-4 * tmp7.exponent) > tolerance)
                    {
                        bflag = true;
                    }
                }

                BigNumber.Copy(guess, last_x);
                ii++;
            }

            BigNumber.Mul(tmp9, tmpN, tmp8);
            BigNumber.Round(tmp8, dst, places);
            dst.exponent += nexp;
        }