/// <summary>
        /// Phân số tối giản.
        /// </summary>
        public void Minimalism()
        {
            BigDecimal n = Minimalism(this.Numerator, this.Denominator);

            Numerator   = Numerator.Divide(n.Abs());
            Denominator = Denominator.SetScale(5, RoundingMode.HalfEven);
            Denominator = Denominator.Divide(n.Abs());
        }
        /// <summary>
        ///   Chuyển số thập phân thành hỗn số.
        /// </summary>
        /// <param name="n">Số thập phân nhận từ bên ngoài.</param>
        /// <returns>Phần thực của hỗn số</returns>
        private static FractionBigNum ChangeFraction(BigDecimal n)
        {
            FractionBigNum frac = new FractionBigNum();

            int sign = n.Sign;

            n = n.Abs();

            BigDecimal whole = n.DivideToIntegralValue(BigDecimal.One);

            BigDecimal decimalPoint = n.Subtract(whole);

            frac.Numerator   = decimalPoint.Multiply(BigDecimal.Ten.Pow(CountDecimal(decimalPoint))).DivideToIntegralValue(BigDecimal.One);
            frac.Denominator = BigDecimal.Ten.Pow(CountDecimal(decimalPoint)).DivideToIntegralValue(BigDecimal.One);
            frac.Minimalism();

            if (!whole.IsZero)
            {
                //If Whole is not zero then we change whole to fraction, add fraction.
                FractionBigNum frac2 = new FractionBigNum(whole, BigDecimal.One);
                frac = frac + frac2;
            }

            frac.Numerator *= sign;

            return(frac);
        }
示例#3
0
        public void Abs(string result, string value)
        {
            var resultDecimal = BigDecimal.Parse(result, CultureInfo.InvariantCulture);
            var valueDecimal  = BigDecimal.Parse(value, CultureInfo.InvariantCulture);

            Assert.Equal(resultDecimal, BigDecimal.Abs(valueDecimal));
        }
示例#4
0
        public void AbsTest3()
        {
            var v1 = new BigDecimal(1.01m);
            var v2 = new BigDecimal(1.01m);

            Assert.AreEqual(v2, BigDecimal.Abs(v1));
        }
 /// <summary>
 /// Phương thức xử lí các số âm ở mẫu, hoặc cùng âm dành cho phân số.
 /// </summary>
 /// <param name="num">Tử số</param>
 /// <param name="demo">Mẫu Số</param>
 private static void ResolveNegative(ref BigDecimal num, ref BigDecimal demo)
 {
     //Kiểm tra các số âm
     if (num.Sign == -1 && demo.Sign == -1)
     {
         num  = num.Abs();
         demo = demo.Abs();
     }
     else
     {
         if (num.Sign == 1 && demo.Sign == -1)
         {
             num  = num.Negate();
             demo = demo.Abs();
         }
     }
 }
示例#6
0
 internal decimal Abs()
 {
     if (_val == null)
     {
         return(this);
     }
     return(_val.Abs());
 }
示例#7
0
 public void Abs()
 {
     BigDecimal big = BigDecimal.Parse("-1234");
     BigDecimal bigabs = big.Abs();
     Assert.IsTrue(bigabs.ToString().Equals("1234"), "the absolute value of -1234 is not 1234");
     big = new BigDecimal(BigInteger.Parse("2345"), 2);
     bigabs = big.Abs();
     Assert.IsTrue(bigabs.ToString().Equals("23.45"), "the absolute value of 23.45 is not 23.45");
 }
示例#8
0
 public SqlNumber Abs()
 {
     if (State == NumericState.None)
     {
         return(new SqlNumber(NumericState.None, innerValue.Abs()));
     }
     if (State == NumericState.NegativeInfinity)
     {
         return(new SqlNumber(NumericState.PositiveInfinity, null));
     }
     return(new SqlNumber(State, null));
 }
示例#9
0
 public Number Abs()
 {
     if (numberState == 0)
     {
         return(new Number(NumberState.None, bigDecimal.Abs()));
     }
     if (numberState == NumberState.NegativeInfinity)
     {
         return(new Number(NumberState.PositiveInfinity, null));
     }
     return(new Number(numberState, null));
 }
示例#10
0
        private static BigDecimal SqrtNewtonRaphson(BigDecimal c, BigDecimal xn, BigDecimal precision)
        {
            BigDecimal fx  = xn.Pow(2).Add(c.Negate());
            BigDecimal fpx = xn.Multiply(new BigDecimal(2));
            BigDecimal xn1 = fx.Divide(fpx, 2 * SqrtDig.ToInt32(), RoundingMode.HalfDown);

            xn1 = xn.Add(xn1.Negate());
            //----
            BigDecimal currentSquare    = xn1.Pow(2);
            BigDecimal currentPrecision = currentSquare.Subtract(c);

            currentPrecision = currentPrecision.Abs();
            if (currentPrecision.CompareTo(precision) <= -1)
            {
                return(xn1);
            }

            return(SqrtNewtonRaphson(c, xn1, precision));
        }
示例#11
0
 public static BigDecimal /*!*/ Abs(RubyContext /*!*/ context, BigDecimal /*!*/ self)
 {
     return(BigDecimal.Abs(GetConfig(context), self));
 }
示例#12
0
 public static void CheckXrpBounds(BigDecimal value)
 {
     value = value.Abs();
     CheckLowerDropBound(value);
     CheckUpperBound(value);
 }
示例#13
0
        public static BigDecimal Hypot(BigDecimal x, BigDecimal y)
        {
            /* compute x^2+y^2
                */
            BigDecimal z = x.Pow(2).Add(y.Pow(2));

            /* truncate to the precision set by x and y. Absolute error = 2*x*xerr+2*y*yerr,
                * where the two errors are 1/2 of the ulp's.  Two intermediate protectio digits.
                */
            BigDecimal zerr = x.Abs().Multiply(x.Ulp()).Add(y.Abs().Multiply(y.Ulp()));
            var mc = new MathContext(2 + ErrorToPrecision(z, zerr));

            /* Pull square root */
            z = Sqrt(z.Round(mc));

            /* Final rounding. Absolute error in the square root is (y*yerr+x*xerr)/z, where zerr holds 2*(x*xerr+y*yerr).
                */
            mc = new MathContext(ErrorToPrecision(z.ToDouble(), 0.5*zerr.ToDouble()/z.ToDouble()));
            return z.Round(mc);
        }
示例#14
0
        public static BigDecimal Sqrt(BigDecimal x, MathContext mc)
        {
            if (x.CompareTo(BigDecimal.Zero) < 0)
                throw new ArithmeticException("negative argument " + x + " of square root");

            if (x.Abs().Subtract(new BigDecimal(System.Math.Pow(10d, -mc.Precision))).CompareTo(BigDecimal.Zero) < 0)
                return ScalePrecision(BigDecimal.Zero, mc);

            /* start the computation from a double precision estimate */
            var s = new BigDecimal(System.Math.Sqrt(x.ToDouble()), mc);
            BigDecimal half = BigDecimal.ValueOf(2);

            /* increase the local accuracy by 2 digits */
            var locmc = new MathContext(mc.Precision + 2, mc.RoundingMode);

            /* relative accuracy requested is 10^(-precision)
                */
            double eps = System.Math.Pow(10.0, -mc.Precision);
            while (true) {
                /* s = s -(s/2-x/2s); test correction s-x/s for being
                        * smaller than the precision requested. The relative correction is 1-x/s^2,
                        * (actually half of this, which we use for a little bit of additional protection).
                        */
                if (System.Math.Abs(BigDecimal.One.Subtract(x.Divide(s.Pow(2, locmc), locmc)).ToDouble()) < eps)
                    break;
                s = s.Add(x.Divide(s, locmc)).Divide(half, locmc);
            }

            return s;
        }
示例#15
0
        public static BigDecimal PowRound(BigDecimal x, Rational q)
        {
            /** Special cases: x^1=x and x^0 = 1
                */
            if (q.CompareTo(BigInteger.One) == 0)
                return x;
            if (q.Sign == 0)
                return BigDecimal.One;
            if (q.IsInteger) {
                /* We are sure that the denominator is positive here, because normalize() has been
                        * called during constrution etc.
                        */
                return PowRound(x, q.Numerator);
            }
            /* Refuse to operate on the general negative basis. The integer q have already been handled above.
                        */
            if (x.CompareTo(BigDecimal.Zero) < 0)
                throw new ArithmeticException("Cannot power negative " + x);
            if (q.IsIntegerFraction) {
                /* Newton method with first estimate in double precision.
                                * The disadvantage of this first line here is that the result must fit in the
                                * standard range of double precision numbers exponents.
                                */
                double estim = System.Math.Pow(x.ToDouble(), q.ToDouble());
                var res = new BigDecimal(estim);

                /* The error in x^q is q*x^(q-1)*Delta(x).
                                * The relative error is q*Delta(x)/x, q times the relative error of x.
                                */
                var reserr = new BigDecimal(0.5*q.Abs().ToDouble()
                                            *x.Ulp().Divide(x.Abs(), MathContext.Decimal64).ToDouble());

                /* The main point in branching the cases above is that this conversion
                                * will succeed for numerator and denominator of q.
                                */
                int qa = q.Numerator.ToInt32();
                int qb = q.Denominator.ToInt32();

                /* Newton iterations. */
                BigDecimal xpowa = PowRound(x, qa);
                for (;;) {
                    /* numerator and denominator of the Newton term.  The major
                                        * disadvantage of this implementation is that the updates of the powers
                                        * of the new estimate are done in full precision calling BigDecimal.pow(),
                                        * which becomes slow if the denominator of q is large.
                                        */
                    BigDecimal nu = res.Pow(qb).Subtract(xpowa);
                    BigDecimal de = MultiplyRound(res.Pow(qb - 1), q.Denominator);

                    /* estimated correction */
                    BigDecimal eps = nu.Divide(de, MathContext.Decimal64);

                    BigDecimal err = res.Multiply(reserr, MathContext.Decimal64);
                    int precDiv = 2 + ErrorToPrecision(eps, err);
                    if (precDiv <= 0) {
                        /* The case when the precision is already reached and any precision
                                                * will do. */
                        eps = nu.Divide(de, MathContext.Decimal32);
                    } else {
                        eps = nu.Divide(de, new MathContext(precDiv));
                    }

                    res = SubtractRound(res, eps);
                    /* reached final precision if the relative error fell below reserr,
                                        * |eps/res| < reserr
                                        */
                    if (eps.Divide(res, MathContext.Decimal64).Abs().CompareTo(reserr) < 0) {
                        /* delete the bits of extra precision kept in this
                                                * working copy.
                                                */
                        return res.Round(new MathContext(ErrorToPrecision(reserr.ToDouble())));
                    }
                }
            }
            /* The error in x^q is q*x^(q-1)*Delta(x) + Delta(q)*x^q*log(x).
                                * The relative error is q/x*Delta(x) + Delta(q)*log(x). Convert q to a floating point
                                * number such that its relative error becomes negligible: Delta(q)/q << Delta(x)/x/log(x) .
                                */
            int precq = 3 + ErrorToPrecision((x.Ulp().Divide(x, MathContext.Decimal64)).ToDouble()
                                             /System.Math.Log(x.ToDouble()));

            /* Perform the actual calculation as exponentiation of two floating point numbers.
                                */
            return Pow(x, q.ToBigDecimal(new MathContext(precq)));
        }
示例#16
0
    public void TestTruncateOnAllArithmeticOperations()
    {
        var savePrecision = BigDecimal.Precision;

        BigDecimal mod1 = BigDecimal.Parse("3141592653589793238462643383279502");
        BigDecimal mod2 = BigDecimal.Parse("27182818284590452");
        BigDecimal neg1 = BigDecimal.Parse("-3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647");
        BigDecimal lrg1 = BigDecimal.Parse("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647");
        BigDecimal lrg2 = BigDecimal.Parse("2.718281828459045235360287471352662497757247093699959574966967");

        var expected1  = "5.859874482";
        var expected2  = "0.4233108251";
        var expected3  = "8.5397342226";
        var expected4  = "0.8652559794";
        var expected5  = "9.869604401";
        var expected6  = "148.4131591";
        var expected7  = "8003077319547306";
        var expected8  = "-3.1415926535";
        var expected9  = "3";
        var expected10 = "4";
        var expected11 = "3.1415926535";

        var actual1  = "";
        var actual2  = "";
        var actual3  = "";
        var actual4  = "";
        var actual5  = "";
        var actual6  = "";
        var actual7  = "";
        var actual8  = "";
        var actual9  = "";
        var actual10 = "";
        var actual11 = "";

        try
        {
            BigDecimal.Precision      = 10;
            BigDecimal.AlwaysTruncate = true;

            TestContext.WriteLine($"E = {BigDecimal.E}");
            TestContext.WriteLine($"{new BigDecimal(lrg1.Mantissa, lrg1.Exponent)}");
            TestContext.WriteLine($"{new BigDecimal(lrg2.Mantissa, lrg2.Exponent)}");

            BigDecimal result1  = BigDecimal.Add(lrg1, lrg2);
            BigDecimal result2  = BigDecimal.Subtract(lrg1, lrg2);
            BigDecimal result3  = BigDecimal.Multiply(lrg1, lrg2);
            BigDecimal result4  = BigDecimal.Divide(lrg2, lrg1);
            BigDecimal result5  = BigDecimal.Pow(lrg1, 2);
            BigDecimal result6  = BigDecimal.Exp(new BigInteger(5));
            BigDecimal result7  = BigDecimal.Mod(mod1, mod2);
            BigDecimal result8  = BigDecimal.Negate(lrg1);
            BigDecimal result9  = BigDecimal.Floor(lrg1);
            BigDecimal result10 = BigDecimal.Ceiling(lrg1);
            BigDecimal result11 = BigDecimal.Abs(lrg1);

            actual1  = result1.ToString();
            actual2  = result2.ToString();
            actual3  = result3.ToString();
            actual4  = result4.ToString();
            actual5  = result5.ToString();
            actual6  = result6.ToString();
            actual7  = result7.ToString();
            actual8  = result8.ToString();
            actual9  = result9.ToString();
            actual10 = result10.ToString();
            actual11 = result11.ToString();
        }
        finally
        {
            BigDecimal.Precision      = savePrecision;
            BigDecimal.AlwaysTruncate = false;
        }

        Assert.AreEqual(expected1, actual1, $"Test Truncate On All Arithmetic Operations  - #1: ");
        Assert.AreEqual(expected2, actual2, $"Test Truncate On All Arithmetic Operations  - #2: ");
        Assert.AreEqual(expected3, actual3, $"Test Truncate On All Arithmetic Operations  - #3: ");
        Assert.AreEqual(expected4, actual4, $"Test Truncate On All Arithmetic Operations  - #4: ");
        Assert.AreEqual(expected5, actual5, $"Test Truncate On All Arithmetic Operations  - #5: ");
        StringAssert.StartsWith(expected6, actual6, $"Test Truncate On All Arithmetic Operations  - #6: ");
        Assert.AreEqual(expected7, actual7, $"Test Truncate On All Arithmetic Operations  - #7: ");
        Assert.AreEqual(expected8, actual8, $"Test Truncate On All Arithmetic Operations  - #8: ");
        Assert.AreEqual(expected9, actual9, $"Test Truncate On All Arithmetic Operations  - #9: ");
        Assert.AreEqual(expected10, actual10, $"Test Truncate On All Arithmetic Operations - #10: ");
        Assert.AreEqual(expected11, actual11, $"Test Truncate On All Arithmetic Operations - #11: ");

        Assert.AreEqual(5000, BigDecimal.Precision, "Restore Precision to 5000");
    }
示例#17
0
 public void AbsTest()
 {
     Assert.AreEqual(BigDecimal.One, BigDecimal.Abs(BigDecimal.MinusOne));
 }