예제 #1
0
 public virtual Number Calculate(BigDecimal num)
 {
     if (num == null)
     {
         return -0;
     }
     return num.Negate();
 }
예제 #2
0
 public static BigDecimal /*!*/ Negate(RubyContext /*!*/ context, BigDecimal /*!*/ self)
 {
     return(BigDecimal.Negate(GetConfig(context), self));
 }
예제 #3
0
        public static BigDecimal Exp(BigDecimal x)
        {
            /* To calculate the value if x is negative, use exp(-x) = 1/exp(x)
                */
            if (x.CompareTo(BigDecimal.Zero) < 0) {
                BigDecimal invx = Exp(x.Negate());
                /* Relative error in inverse of invx is the same as the relative errror in invx.
                        * This is used to define the precision of the result.
                        */
                var mc = new MathContext(invx.Precision);
                return BigDecimal.One.Divide(invx, mc);
            }
            if (x.CompareTo(BigDecimal.Zero) == 0) {
                /* recover the valid number of digits from x.ulp(), if x hits the
                        * zero. The x.precision() is 1 then, and does not provide this information.
                        */
                return ScalePrecision(BigDecimal.One, -(int) (System.Math.Log10(x.Ulp().ToDouble())));
            }
            /* Push the number in the Taylor expansion down to a small
                        * value where TAYLOR_NTERM terms will do. If x<1, the n-th term is of the order
                        * x^n/n!, and equal to both the absolute and relative error of the result
                        * since the result is close to 1. The x.ulp() sets the relative and absolute error
                        * of the result, as estimated from the first Taylor term.
                        * We want x^TAYLOR_NTERM/TAYLOR_NTERM! < x.ulp, which is guaranteed if
                        * x^TAYLOR_NTERM < TAYLOR_NTERM*(TAYLOR_NTERM-1)*...*x.ulp.
                        */
            double xDbl = x.ToDouble();
            double xUlpDbl = x.Ulp().ToDouble();
            if (System.Math.Pow(xDbl, TaylorNterm) < TaylorNterm*(TaylorNterm - 1.0)*(TaylorNterm - 2.0)*xUlpDbl) {
                /* Add TAYLOR_NTERM terms of the Taylor expansion (Euler's sum formula)
                                */
                BigDecimal resul = BigDecimal.One;

                /* x^i */
                BigDecimal xpowi = BigDecimal.One;

                /* i factorial */
                BigInteger ifac = BigInteger.One;

                /* TAYLOR_NTERM terms to be added means we move x.ulp() to the right
                                * for each power of 10 in TAYLOR_NTERM, so the addition won't add noise beyond
                                * what's already in x.
                                */
                var mcTay = new MathContext(ErrorToPrecision(1d, xUlpDbl/TaylorNterm));
                for (int i = 1; i <= TaylorNterm; i++) {
                    ifac = ifac.Multiply(BigInteger.ValueOf(i));
                    xpowi = xpowi.Multiply(x);
                    BigDecimal c = xpowi.Divide(new BigDecimal(ifac), mcTay);
                    resul = resul.Add(c);
                    if (System.Math.Abs(xpowi.ToDouble()) < i &&
                        System.Math.Abs(c.ToDouble()) < 0.5*xUlpDbl)
                        break;
                }
                /* exp(x+deltax) = exp(x)(1+deltax) if deltax is <<1. So the relative error
                                * in the result equals the absolute error in the argument.
                                */
                var mc = new MathContext(ErrorToPrecision(xUlpDbl/2d));
                return resul.Round(mc);
            } else {
                /* Compute exp(x) = (exp(0.1*x))^10. Division by 10 does not lead
                                * to loss of accuracy.
                                */
                var exSc = (int) (1.0 - System.Math.Log10(TaylorNterm*(TaylorNterm - 1.0)*(TaylorNterm - 2.0)*xUlpDbl
                                                          /System.Math.Pow(xDbl, TaylorNterm))/(TaylorNterm - 1.0));
                BigDecimal xby10 = x.ScaleByPowerOfTen(-exSc);
                BigDecimal expxby10 = Exp(xby10);

                /* Final powering by 10 means that the relative error of the result
                                * is 10 times the relative error of the base (First order binomial expansion).
                                * This looses one digit.
                                */
                var mc = new MathContext(expxby10.Precision - exSc);
                /* Rescaling the powers of 10 is done in chunks of a maximum of 8 to avoid an invalid operation
                                * response by the BigDecimal.pow library or integer overflow.
                                */
                while (exSc > 0) {
                    int exsub = System.Math.Min(8, exSc);
                    exSc -= exsub;
                    var mctmp = new MathContext(expxby10.Precision - exsub + 2);
                    int pex = 1;
                    while (exsub-- > 0)
                        pex *= 10;
                    expxby10 = expxby10.Pow(pex, mctmp);
                }
                return expxby10.Round(mc);
            }
        }
예제 #4
0
        public static BigDecimal Cos(BigDecimal x)
        {
            if (x.CompareTo(BigDecimal.Zero) < 0)
                return Cos(x.Negate());
            if (x.CompareTo(BigDecimal.Zero) == 0)
                return BigDecimal.One;
            /* reduce modulo 2pi
                        */
            BigDecimal res = Mod2Pi(x);
            double errpi = 0.5*System.Math.Abs(x.Ulp().ToDouble());
            var mc = new MathContext(2 + ErrorToPrecision(3.14159, errpi));
            BigDecimal p = PiRound(mc);
            mc = new MathContext(x.Precision);
            if (res.CompareTo(p) > 0) {
                /* pi<x<=2pi: cos(x)= - cos(x-pi)
                                */
                return Cos(SubtractRound(res, p)).Negate();
            }
            if (res.Multiply(BigDecimal.ValueOf(2)).CompareTo(p) > 0) {
                /* pi/2<x<=pi: cos(x)= -cos(pi-x)
                                */
                return Cos(SubtractRound(p, res)).Negate();
            }
            /* for the range 0<=x<Pi/2 one could use cos(2x)= 1-2*sin^2(x)
                                * to split this further, or use the cos up to pi/4 and the sine higher up.
                                        throw new ProviderException("Not implemented: cosine ") ;
                                */
            if (res.Multiply(BigDecimal.ValueOf(4)).CompareTo(p) > 0) {
                /* x>pi/4: cos(x) = sin(pi/2-x)
                                        */
                return Sin(SubtractRound(p.Divide(BigDecimal.ValueOf(2)), res));
            }
            /* Simple Taylor expansion, sum_{i=0..infinity} (-1)^(..)res^(2i)/(2i)! */
            BigDecimal resul = BigDecimal.One;

            /* x^i */
            BigDecimal xpowi = BigDecimal.One;

            /* 2i factorial */
            BigInteger ifac = BigInteger.One;

            /* The absolute error in the result is the error in x^2/2 which is x times the error in x.
                                        */
            double xUlpDbl = 0.5*res.Ulp().ToDouble()*res.ToDouble();

            /* The error in the result is set by the error in x^2/2 itself, xUlpDbl.
                                        * We need at most k terms to push x^(2k+1)/(2k+1)! below this value.
                                        * x^(2k) < xUlpDbl; (2k)*log(x) < log(xUlpDbl);
                                        */
            int k = (int) (System.Math.Log(xUlpDbl)/System.Math.Log(res.ToDouble()))/2;
            var mcTay = new MathContext(ErrorToPrecision(1d, xUlpDbl/k));
            for (int i = 1;; i++) {
                /* TBD: at which precision will 2*i-1 or 2*i overflow?
                                                */
                ifac = ifac.Multiply(BigInteger.ValueOf((2*i - 1)));
                ifac = ifac.Multiply(BigInteger.ValueOf((2*i)));
                xpowi = xpowi.Multiply(res).Multiply(res).Negate();
                BigDecimal corr = xpowi.Divide(new BigDecimal(ifac), mcTay);
                resul = resul.Add(corr);
                if (corr.Abs().ToDouble() < 0.5*xUlpDbl)
                    break;
            }
            /* The error in the result is governed by the error in x itself.
                                        */
            mc = new MathContext(ErrorToPrecision(resul.ToDouble(), xUlpDbl));
            return resul.Round(mc);
        }
예제 #5
0
        public static BigDecimal Cot(BigDecimal x)
        {
            if (x.CompareTo(BigDecimal.Zero) == 0) {
                throw new ArithmeticException("Cannot take cot of zero " + x);
            }
            if (x.CompareTo(BigDecimal.Zero) < 0) {
                return Cot(x.Negate()).Negate();
            }
            /* reduce modulo pi
                        */
            BigDecimal res = ModPi(x);

            /* absolute error in the result is err(x)/sin^2(x) to lowest order
                        */
            double xDbl = res.ToDouble();
            double xUlpDbl = x.Ulp().ToDouble()/2d;
            double eps = xUlpDbl/2d/System.Math.Pow(System.Math.Sin(xDbl), 2d);

            BigDecimal xhighpr = ScalePrecision(res, 2);
            BigDecimal xhighprSq = MultiplyRound(xhighpr, xhighpr);

            var mc = new MathContext(ErrorToPrecision(xhighpr.ToDouble(), eps));
            BigDecimal resul = BigDecimal.One.Divide(xhighpr, mc);

            /* x^(2i-1) */
            BigDecimal xpowi = xhighpr;

            var b = new Bernoulli();

            /* 2^(2i) */
            var fourn = BigInteger.Parse("4");
            /* (2i)! */
            BigInteger fac = BigInteger.One;

            for (int i = 1;; i++) {
                Rational f = b[2*i];
                fac = fac.Multiply(BigInteger.ValueOf((2*i))).Multiply(BigInteger.ValueOf((2*i - 1)));
                f = f.Multiply(fourn).Divide(fac);
                BigDecimal c = MultiplyRound(xpowi, f);
                if (i%2 == 0)
                    resul = resul.Add(c);
                else
                    resul = resul.Subtract(c);
                if (System.Math.Abs(c.ToDouble()) < 0.1*eps)
                    break;

                fourn = fourn.ShiftLeft(2);
                xpowi = MultiplyRound(xpowi, xhighprSq);
            }
            mc = new MathContext(ErrorToPrecision(resul.ToDouble(), eps));
            return resul.Round(mc);
        }
예제 #6
0
        public static BigDecimal Asin(BigDecimal x)
        {
            if (x.CompareTo(BigDecimal.One) > 0 ||
                x.CompareTo(BigDecimal.One.Negate()) < 0) {
                throw new ArithmeticException("Out of range argument " + x + " of asin");
            }
            if (x.CompareTo(BigDecimal.Zero) == 0)
                return BigDecimal.Zero;
            if (x.CompareTo(BigDecimal.One) == 0) {
                /* arcsin(1) = pi/2
                        */
                double errpi = System.Math.Sqrt(x.Ulp().ToDouble());
                var mc = new MathContext(ErrorToPrecision(3.14159, errpi));
                return PiRound(mc).Divide(new BigDecimal(2));
            }
            if (x.CompareTo(BigDecimal.Zero) < 0) {
                return Asin(x.Negate()).Negate();
            }
            if (x.ToDouble() > 0.7) {
                BigDecimal xCompl = BigDecimal.One.Subtract(x);
                double xDbl = x.ToDouble();
                double xUlpDbl = x.Ulp().ToDouble()/2d;
                double eps = xUlpDbl/2d/System.Math.Sqrt(1d - System.Math.Pow(xDbl, 2d));

                BigDecimal xhighpr = ScalePrecision(xCompl, 3);
                BigDecimal xhighprV = DivideRound(xhighpr, 4);

                BigDecimal resul = BigDecimal.One;

                /* x^(2i+1) */
                BigDecimal xpowi = BigDecimal.One;

                /* i factorial */
                BigInteger ifacN = BigInteger.One;
                BigInteger ifacD = BigInteger.One;

                for (int i = 1;; i++) {
                    ifacN = ifacN.Multiply(BigInteger.ValueOf((2*i - 1)));
                    ifacD = ifacD.Multiply(BigInteger.ValueOf(i));
                    if (i == 1)
                        xpowi = xhighprV;
                    else
                        xpowi = MultiplyRound(xpowi, xhighprV);
                    BigDecimal c = DivideRound(MultiplyRound(xpowi, ifacN),
                        ifacD.Multiply(BigInteger.ValueOf((2*i + 1))));
                    resul = resul.Add(c);
                    /* series started 1+x/12+... which yields an estimate of the sum's error
                                */
                    if (System.Math.Abs(c.ToDouble()) < xUlpDbl/120d)
                        break;
                }
                /* sqrt(2*z)*(1+...)
                        */
                xpowi = Sqrt(xhighpr.Multiply(new BigDecimal(2)));
                resul = MultiplyRound(xpowi, resul);

                var mc = new MathContext(resul.Precision);
                BigDecimal pihalf = PiRound(mc).Divide(new BigDecimal(2));

                mc = new MathContext(ErrorToPrecision(resul.ToDouble(), eps));
                return pihalf.Subtract(resul, mc);
            } else {
                /* absolute error in the result is err(x)/sqrt(1-x^2) to lowest order
                        */
                double xDbl = x.ToDouble();
                double xUlpDbl = x.Ulp().ToDouble()/2d;
                double eps = xUlpDbl/2d/System.Math.Sqrt(1d - System.Math.Pow(xDbl, 2d));

                BigDecimal xhighpr = ScalePrecision(x, 2);
                BigDecimal xhighprSq = MultiplyRound(xhighpr, xhighpr);

                BigDecimal resul = xhighpr.Plus();

                /* x^(2i+1) */
                BigDecimal xpowi = xhighpr;

                /* i factorial */
                BigInteger ifacN = BigInteger.One;
                BigInteger ifacD = BigInteger.One;

                for (int i = 1;; i++) {
                    ifacN = ifacN.Multiply(BigInteger.ValueOf((2*i - 1)));
                    ifacD = ifacD.Multiply(BigInteger.ValueOf((2*i)));
                    xpowi = MultiplyRound(xpowi, xhighprSq);
                    BigDecimal c = DivideRound(MultiplyRound(xpowi, ifacN),
                        ifacD.Multiply(BigInteger.ValueOf((2*i + 1))));
                    resul = resul.Add(c);
                    if (System.Math.Abs(c.ToDouble()) < 0.1*eps)
                        break;
                }
                var mc = new MathContext(ErrorToPrecision(resul.ToDouble(), eps));
                return resul.Round(mc);
            }
        }
예제 #7
0
 public static BigDecimal Cbrt(BigDecimal x)
 {
     if (x.CompareTo(BigDecimal.Zero) < 0)
         return Root(3, x.Negate()).Negate();
     return Root(3, x);
 }
예제 #8
0
        public static BigDecimal Tan(BigDecimal x)
        {
            if (x.CompareTo(BigDecimal.Zero) == 0)
                return BigDecimal.Zero;
            if (x.CompareTo(BigDecimal.Zero) < 0) {
                return Tan(x.Negate()).Negate();
            }
            /* reduce modulo pi
                        */
            BigDecimal res = ModPi(x);

            /* absolute error in the result is err(x)/cos^2(x) to lowest order
                        */
            double xDbl = res.ToDouble();
            double xUlpDbl = x.Ulp().ToDouble()/2d;
            double eps = xUlpDbl/2d/System.Math.Pow(System.Math.Cos(xDbl), 2d);

            if (xDbl > 0.8) {
                /* tan(x) = 1/cot(x) */
                BigDecimal co = Cot(x);
                var mc = new MathContext(ErrorToPrecision(1d/co.ToDouble(), eps));
                return BigDecimal.One.Divide(co, mc);
            } else {
                BigDecimal xhighpr = ScalePrecision(res, 2);
                BigDecimal xhighprSq = MultiplyRound(xhighpr, xhighpr);

                BigDecimal resul = xhighpr.Plus();

                /* x^(2i+1) */
                BigDecimal xpowi = xhighpr;

                var b = new Bernoulli();

                /* 2^(2i) */
                BigInteger fourn = BigInteger.ValueOf(4);
                /* (2i)! */
                BigInteger fac = BigInteger.ValueOf(2);

                for (int i = 2;; i++) {
                    Rational f = b[2*i].Abs();
                    fourn = fourn.ShiftLeft(2);
                    fac = fac.Multiply(BigInteger.ValueOf((2*i))).Multiply(BigInteger.ValueOf((2*i - 1)));
                    f = f.Multiply(fourn).Multiply(fourn.Subtract(BigInteger.One)).Divide(fac);
                    xpowi = MultiplyRound(xpowi, xhighprSq);
                    BigDecimal c = MultiplyRound(xpowi, f);
                    resul = resul.Add(c);
                    if (System.Math.Abs(c.ToDouble()) < 0.1*eps)
                        break;
                }
                var mc = new MathContext(ErrorToPrecision(resul.ToDouble(), eps));
                return resul.Round(mc);
            }
        }
예제 #9
0
        public static BigDecimal Sin(BigDecimal x)
        {
            if (x.CompareTo(BigDecimal.Zero) < 0)
                return Sin(x.Negate()).Negate();
            if (x.CompareTo(BigDecimal.Zero) == 0)
                return BigDecimal.Zero;
            /* reduce modulo 2pi
                        */
            BigDecimal res = Mod2Pi(x);
            double errpi = 0.5*System.Math.Abs(x.Ulp().ToDouble());
            var mc = new MathContext(2 + ErrorToPrecision(3.14159, errpi));
            BigDecimal p = PiRound(mc);
            mc = new MathContext(x.Precision);
            if (res.CompareTo(p) > 0) {
                /* pi<x<=2pi: sin(x)= - sin(x-pi)
                                */
                return Sin(SubtractRound(res, p)).Negate();
            }
            if (res.Multiply(BigDecimal.ValueOf(2)).CompareTo(p) > 0) {
                /* pi/2<x<=pi: sin(x)= sin(pi-x)
                                */
                return Sin(SubtractRound(p, res));
            }
            /* for the range 0<=x<Pi/2 one could use sin(2x)=2sin(x)cos(x)
                                * to split this further. Here, use the sine up to pi/4 and the cosine higher up.
                                */
            if (res.Multiply(BigDecimal.ValueOf(4)).CompareTo(p) > 0) {
                /* x>pi/4: sin(x) = cos(pi/2-x)
                                        */
                return Cos(SubtractRound(p.Divide(BigDecimal.ValueOf(2)), res));
            }
            /* Simple Taylor expansion, sum_{i=1..infinity} (-1)^(..)res^(2i+1)/(2i+1)! */
            BigDecimal resul = res;

            /* x^i */
            BigDecimal xpowi = res;

            /* 2i+1 factorial */
            BigInteger ifac = BigInteger.One;

            /* The error in the result is set by the error in x itself.
                                        */
            double xUlpDbl = res.Ulp().ToDouble();

            /* The error in the result is set by the error in x itself.
                                        * We need at most k terms to squeeze x^(2k+1)/(2k+1)! below this value.
                                        * x^(2k+1) < x.ulp; (2k+1)*log10(x) < -x.precision; 2k*log10(x)< -x.precision;
                                        * 2k*(-log10(x)) > x.precision; 2k*log10(1/x) > x.precision
                                        */
            int k = (int) (res.Precision/System.Math.Log10(1.0/res.ToDouble()))/2;
            var mcTay = new MathContext(ErrorToPrecision(res.ToDouble(), xUlpDbl/k));
            for (int i = 1;; i++) {
                /* TBD: at which precision will 2*i or 2*i+1 overflow?
                                                */
                ifac = ifac.Multiply(BigInteger.ValueOf(2*i));
                ifac = ifac.Multiply(BigInteger.ValueOf((2*i + 1)));
                xpowi = xpowi.Multiply(res).Multiply(res).Negate();
                BigDecimal corr = xpowi.Divide(new BigDecimal(ifac), mcTay);
                resul = resul.Add(corr);
                if (corr.Abs().ToDouble() < 0.5*xUlpDbl)
                    break;
            }
            /* The error in the result is set by the error in x itself.
                                        */
            mc = new MathContext(res.Precision);
            return resul.Round(mc);
        }
예제 #10
0
 public static Number operator -(Number a)
 {
     return(BigDecimal.Negate(new BigDecimal.Config(), a.value));
 }
예제 #11
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");
    }
예제 #12
0
 public void Negate()
 {
     BigDecimal negate1 = new BigDecimal(value2, 7);
     Assert.IsTrue(negate1.Negate().ToString().Equals("-1233.4560000"), "the negate of 1233.4560000 is not -1233.4560000");
     negate1 = BigDecimal.Parse("-23465839");
     Assert.IsTrue(negate1.Negate().ToString().Equals("23465839"), "the negate of -23465839 is not 23465839");
     negate1 = new BigDecimal(-3.456E6);
     Assert.IsTrue(negate1.Negate().Negate().Equals(negate1), "the negate of -3.456E6 is not 3.456E6");
 }