コード例 #1
0
 public void Abs()
 {
     Assert.True(BigMath.Abs(-aZillion).Equals(BigMath.Abs(aZillion)), "Invalid number returned for zillion");
     Assert.True(BigMath.Abs(-zero).Equals(zero), "Invalid number returned for zero neg");
     Assert.True(BigMath.Abs(zero).Equals(zero), "Invalid number returned for zero");
     Assert.True(BigMath.Abs(-two).Equals(two), "Invalid number returned for two");
 }
コード例 #2
0
        private void TestDiv(BigInteger i1, BigInteger i2)
        {
            BigInteger q = i1 / i2;
            BigInteger r = BigMath.Remainder(i1, i2);
            BigInteger remainder;
            BigInteger quotient = BigMath.DivideAndRemainder(i1, i2, out remainder);

            Assert.True(q.Equals(quotient), "Divide and DivideAndRemainder do not agree");
            Assert.True(r.Equals(remainder), "Remainder and DivideAndRemainder do not agree");
            Assert.True(q.Sign != 0 || q.Equals(zero), "signum and equals(zero) do not agree on quotient");
            Assert.True(r.Sign != 0 || r.Equals(zero), "signum and equals(zero) do not agree on remainder");
            Assert.True(q.Sign == 0 || q.Sign == i1.Sign * i2.Sign, "wrong sign on quotient");
            Assert.True(r.Sign == 0 || r.Sign == i1.Sign, "wrong sign on remainder");
            Assert.True(BigMath.Abs(r).CompareTo(BigMath.Abs(i2)) < 0, "remainder out of range");
            Assert.True(((BigMath.Abs(q) + one) * BigMath.Abs(i2)).CompareTo(BigMath.Abs(i1)) > 0, "quotient too small");
            Assert.True((BigMath.Abs(q) * BigMath.Abs(i2)).CompareTo(BigMath.Abs(i1)) <= 0, "quotient too large");
            BigInteger p = q * i2;
            BigInteger a = p + r;

            Assert.True(a.Equals(i1), "(a/b)*b+(a%b) != a");
            try {
                BigInteger mod = i1 % i2;
                Assert.True(mod.Sign >= 0, "mod is negative");
                Assert.True(BigMath.Abs(mod).CompareTo(BigMath.Abs(i2)) < 0, "mod out of range");
                Assert.True(r.Sign < 0 || r.Equals(mod), "positive remainder == mod");
                Assert.True(r.Sign >= 0 || r.Equals(mod - i2), "negative remainder == mod - divisor");
            } catch (ArithmeticException e) {
                Assert.True(i2.Sign <= 0, "mod fails on negative divisor only");
            }
        }
コード例 #3
0
        public void Abs()
        {
            BigDecimal big    = BigDecimal.Parse("-1234");
            BigDecimal bigabs = BigMath.Abs(big);

            Assert.True(bigabs.ToString().Equals("1234"), "the absolute value of -1234 is not 1234");
            big    = new BigDecimal(BigInteger.Parse("2345"), 2);
            bigabs = BigMath.Abs(big);
            Assert.True(bigabs.ToString().Equals("23.45"), "the absolute value of 23.45 is not 23.45");
        }
コード例 #4
0
        /** @see BigInteger#ToDouble() */

        public static double BigInteger2Double(BigInteger val)
        {
            // val.bitLength() < 64
            if ((val.numberLength < 2) ||
                ((val.numberLength == 2) && (val.Digits[1] > 0)))
            {
                return(val.ToInt64());
            }
            // val.bitLength() >= 33 * 32 > 1024
            if (val.numberLength > 32)
            {
                return((val.Sign > 0) ? Double.PositiveInfinity
                                                : Double.NegativeInfinity);
            }
            int  bitLen   = BigMath.Abs(val).BitLength;
            long exponent = bitLen - 1;
            int  delta    = bitLen - 54;
            // We need 54 top bits from this, the 53th bit is always 1 in lVal.
            long lVal = (BigMath.Abs(val) >> delta).ToInt64();

            /*
             * Take 53 bits from lVal to mantissa. The least significant bit is
             * needed for rounding.
             */
            long mantissa = lVal & 0x1FFFFFFFFFFFFFL;

            if (exponent == 1023)
            {
                if (mantissa == 0X1FFFFFFFFFFFFFL)
                {
                    return((val.Sign > 0) ? Double.PositiveInfinity
                                                        : Double.NegativeInfinity);
                }
                if (mantissa == 0x1FFFFFFFFFFFFEL)
                {
                    return((val.Sign > 0) ? Double.MaxValue : -Double.MaxValue);
                }
            }
            // Round the mantissa
            if (((mantissa & 1) == 1) &&
                (((mantissa & 2) == 2) || BitLevel.NonZeroDroppedBits(delta,
                                                                      val.Digits)))
            {
                mantissa += 2;
            }
            mantissa >>= 1;             // drop the rounding bit
            // long resSign = (val.sign < 0) ? 0x8000000000000000L : 0;
            long resSign = (val.Sign < 0) ? Int64.MinValue : 0;

            exponent = ((1023 + exponent) << 52) & 0x7FF0000000000000L;
            long result = resSign | exponent | mantissa;

            return(BitConverter.Int64BitsToDouble(result));
        }
コード例 #5
0
        public static BigDecimal DivideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale,
                                                   RoundingMode roundingMode)
        {
            BigInteger remainder;
            BigInteger quotient = BigMath.DivideAndRemainder(scaledDividend, scaledDivisor, out remainder);

            if (remainder.Sign == 0)
            {
                return(new BigDecimal(quotient, scale));
            }
            int sign = scaledDividend.Sign * scaledDivisor.Sign;
            int compRem;             // 'compare to remainder'

            if (scaledDivisor.BitLength < 63)
            {
                // 63 in order to avoid out of long after <<1
                long rem     = remainder.ToInt64();
                long divisor = scaledDivisor.ToInt64();
                compRem = BigDecimal.LongCompareTo(System.Math.Abs(rem) << 1, System.Math.Abs(divisor));
                // To look if there is a carry
                compRem = BigDecimal.RoundingBehavior(BigInteger.TestBit(quotient, 0) ? 1 : 0,
                                                      sign * (5 + compRem), roundingMode);
            }
            else
            {
                // Checking if:  remainder * 2 >= scaledDivisor
                compRem = BigMath.Abs(remainder).ShiftLeftOneBit().CompareTo(BigMath.Abs(scaledDivisor));
                compRem = BigDecimal.RoundingBehavior(BigInteger.TestBit(quotient, 0) ? 1 : 0,
                                                      sign * (5 + compRem), roundingMode);
            }
            if (compRem != 0)
            {
                if (quotient.BitLength < 63)
                {
                    return(BigDecimal.Create(quotient.ToInt64() + compRem, scale));
                }
                quotient += BigInteger.FromInt64(compRem);
                return(new BigDecimal(quotient, scale));
            }
            // Constructing the result with the appropriate unscaled value
            return(new BigDecimal(quotient, scale));
        }
コード例 #6
0
        public void MathContextConstruction()
        {
            String       a         = "-12380945E+61";
            BigDecimal   aNumber   = BigDecimal.Parse(a);
            int          precision = 6;
            RoundingMode rm        = RoundingMode.HalfDown;
            MathContext  mcIntRm   = new MathContext(precision, rm);
            MathContext  mcStr     = MathContext.Parse("precision=6 roundingMode=HALFDOWN");
            MathContext  mcInt     = new MathContext(precision);
            BigDecimal   res       = BigMath.Abs(aNumber, mcInt);

            Assert.Equal(res, BigDecimal.Parse("1.23809E+68"));

            Assert.Equal(mcIntRm, mcStr);

            Assert.Equal(mcInt.Equals(mcStr), false);

            Assert.Equal(mcIntRm.GetHashCode(), mcStr.GetHashCode());

            Assert.Equal(mcIntRm.ToString(), "precision=6 roundingMode=HalfDown");
        }
コード例 #7
0
        /**
         * Returns this {@code BigDecimal} as a double value. If {@code this} is too
         * big to be represented as an float, then {@code Double.POSITIVE_INFINITY}
         * or {@code Double.NEGATIVE_INFINITY} is returned.
         * <p>
         * Note, that if the unscaled value has more than 53 significant digits,
         * then this decimal cannot be represented exactly in a double variable. In
         * this case the result is rounded.
         * <p>
         * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
         * represented exactly as a double, and thus {@code x1.equals(new
         * BigDecimal(x1.ToDouble())} returns {@code false} for this case.
         * <p>
         * Similarly, if the instance {@code new BigDecimal(9007199254740993L)} is
         * converted to a double, the result is {@code 9.007199254740992E15}.
         * <p>
         *
         * @return this {@code BigDecimal} as a double value.
         */

        public double ToDouble()
        {
            int        sign     = Sign;
            int        exponent = 1076;      // bias + 53
            int        lowestSetBit;
            int        discardedSize;
            long       powerOfTwo = this._bitLength - (long)(_scale / Log10Of2);
            long       bits;       // IEEE-754 Standard
            long       tempBits;   // for temporal calculations
            BigInteger mantisa;

            if ((powerOfTwo < -1074) || (sign == 0))
            {
                // Cases which 'this' is very small
                return(sign * 0.0d);
            }
            else if (powerOfTwo > 1025)
            {
                // Cases which 'this' is very large
                return(sign * Double.PositiveInfinity);
            }

            mantisa = BigMath.Abs(GetUnscaledValue());

            // Let be:  this = [u,s], with s > 0
            if (_scale <= 0)
            {
                // mantisa = abs(u) * 10^s
                mantisa = mantisa * Multiplication.PowerOf10(-_scale);
            }
            else
            {
                // (scale > 0)
                BigInteger quotient;
                BigInteger remainder;
                BigInteger powerOfTen = Multiplication.PowerOf10(_scale);
                int        k          = 100 - (int)powerOfTwo;
                int        compRem;

                if (k > 0)
                {
                    /* Computing (mantisa * 2^k) , where 'k' is a enough big
                     * power of '2' to can divide by 10^s */
                    mantisa   = mantisa << k;
                    exponent -= k;
                }

                // Computing (mantisa * 2^k) / 10^s
                quotient = BigMath.DivideAndRemainder(mantisa, powerOfTen, out remainder);

                // To check if the fractional part >= 0.5
                compRem = remainder.ShiftLeftOneBit().CompareTo(powerOfTen);

                // To add two rounded bits at end of mantisa
                mantisa   = (quotient << 2) + BigInteger.FromInt64((compRem * (compRem + 3)) / 2 + 1);
                exponent -= 2;
            }
            lowestSetBit  = mantisa.LowestSetBit;
            discardedSize = mantisa.BitLength - 54;
            if (discardedSize > 0)
            {
                // (n > 54)
                // mantisa = (abs(u) * 10^s) >> (n - 54)
                bits     = (mantisa >> discardedSize).ToInt64();
                tempBits = bits;

                // #bits = 54, to check if the discarded fraction produces a carry
                if ((((bits & 1) == 1) && (lowestSetBit < discardedSize)) ||
                    ((bits & 3) == 3))
                {
                    bits += 2;
                }
            }
            else
            {
                // (n <= 54)
                // mantisa = (abs(u) * 10^s) << (54 - n)
                bits     = mantisa.ToInt64() << -discardedSize;
                tempBits = bits;

                // #bits = 54, to check if the discarded fraction produces a carry:
                if ((bits & 3) == 3)
                {
                    bits += 2;
                }
            }

            // Testing bit 54 to check if the carry creates a new binary digit
            if ((bits & 0x40000000000000L) == 0)
            {
                // To drop the last bit of mantisa (first discarded)
                bits >>= 1;

                // exponent = 2^(s-n+53+bias)
                exponent += discardedSize;
            }
            else
            {
                // #bits = 54
                bits    >>= 2;
                exponent += discardedSize + 1;
            }

            // To test if the 53-bits number fits in 'double'
            if (exponent > 2046)
            {
                // (exponent - bias > 1023)
                return(sign * Double.PositiveInfinity);
            }

            if (exponent <= 0)
            {
                // (exponent - bias <= -1023)
                // Denormalized numbers (having exponent == 0)
                if (exponent < -53)
                {
                    // exponent - bias < -1076
                    return(sign * 0.0d);
                }

                // -1076 <= exponent - bias <= -1023
                // To discard '- exponent + 1' bits
                bits     = tempBits >> 1;
                tempBits = bits & Utils.URShift(-1L, (63 + exponent));
                bits   >>= (-exponent);

                // To test if after discard bits, a new carry is generated
                if (((bits & 3) == 3) || (((bits & 1) == 1) && (tempBits != 0) &&
                                          (lowestSetBit < discardedSize)))
                {
                    bits += 1;
                }
                exponent = 0;
                bits   >>= 1;
            }

            // Construct the 64 double bits: [sign(1), exponent(11), mantisa(52)]
            // bits = (long)((ulong)sign & 0x8000000000000000L) | ((long)exponent << 52) | (bits & 0xFFFFFFFFFFFFFL);
            bits = sign & Int64.MinValue | ((long)exponent << 52) | (bits & 0xFFFFFFFFFFFFFL);
            return(BitConverter.Int64BitsToDouble(bits));
        }
コード例 #8
0
ファイル: BigInteger.cs プロジェクト: bugbit/algebra
 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
 {
     info.AddValue("sign", sign);
     byte[] magn = BigMath.Abs(this).ToByteArray();
     info.AddValue("magnitude", magn, typeof(byte[]));
 }
コード例 #9
0
ファイル: BigInteger.cs プロジェクト: bugbit/algebra
 /**
  * Tests whether this {@code BigInteger} is probably prime. If {@code true}
  * is returned, then this is prime with a probability beyond
  * (1-1/2^certainty). If {@code false} is returned, then this is definitely
  * composite. If the argument {@code certainty} <= 0, then this method
  * returns true.
  *
  * @param certainty
  *            tolerated primality uncertainty.
  * @return {@code true}, if {@code this} is probably prime, {@code false}
  *         otherwise.
  */
 public static bool IsProbablePrime(BigInteger value, int certainty, CancellationToken argCancelToken)
 {
     return(Primality.IsProbablePrime(BigMath.Abs(value), certainty, argCancelToken));
 }
コード例 #10
0
        /** @see BigInteger#ToString(int) */

        public static string BigInteger2String(BigInteger val, int radix)
        {
            int sign         = val.Sign;
            int numberLength = val.numberLength;

            int[] digits = val.Digits;

            if (sign == 0)
            {
                return("0");                //$NON-NLS-1$
            }
            if (numberLength == 1)
            {
                int  highDigit = digits[numberLength - 1];
                long v         = highDigit & 0xFFFFFFFFL;
                if (sign < 0)
                {
                    // Long.ToString has different semantic from C# for negative numbers
                    return("-" + Convert.ToString(v, radix));
                }
                return(Convert.ToString(v, radix));
            }
            if ((radix == 10) || (radix < CharHelper.MIN_RADIX) ||
                (radix > CharHelper.MAX_RADIX))
            {
                return(val.ToString());
            }
            double bitsForRadixDigit;

            bitsForRadixDigit = System.Math.Log(radix) / System.Math.Log(2);
            int resLengthInChars = (int)(BigMath.Abs(val).BitLength / bitsForRadixDigit + ((sign < 0) ? 1
                                        : 0)) + 1;

            char[] result      = new char[resLengthInChars];
            int    currentChar = resLengthInChars;
            int    resDigit;

            if (radix != 16)
            {
                int[] temp = new int[numberLength];
                Array.Copy(digits, 0, temp, 0, numberLength);
                int tempLen     = numberLength;
                int charsPerInt = digitFitInInt[radix];
                int i;
                // get the maximal power of radix that fits in int
                int bigRadix = bigRadices[radix - 2];
                while (true)
                {
                    // divide the array of digits by bigRadix and convert remainders
                    // to CharHelpers collecting them in the char array
                    resDigit = Division.DivideArrayByInt(temp, temp, tempLen, bigRadix);
                    int previous = currentChar;
                    do
                    {
                        result[--currentChar] = CharHelper.forDigit(
                            resDigit % radix, radix);
                    } while (((resDigit /= radix) != 0) && (currentChar != 0));
                    int delta = charsPerInt - previous + currentChar;
                    for (i = 0; i < delta && currentChar > 0; i++)
                    {
                        result[--currentChar] = '0';
                    }
                    for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--)
                    {
                        ;
                    }
                    tempLen = i + 1;
                    if ((tempLen == 1) && (temp[0] == 0))                       // the quotient is 0
                    {
                        break;
                    }
                }
            }
            else
            {
                // radix == 16
                for (int i = 0; i < numberLength; i++)
                {
                    for (int j = 0; (j < 8) && (currentChar > 0); j++)
                    {
                        resDigit = digits[i] >> (j << 2) & 0xf;
                        result[--currentChar] = CharHelper.forDigit(resDigit, 16);
                    }
                }
            }
            while (result[currentChar] == '0')
            {
                currentChar++;
            }
            if (sign == -1)
            {
                result[--currentChar] = '-';
            }
            return(new String(result, currentChar, resLengthInChars - currentChar));
        }
コード例 #11
0
        public static BigDecimal Divide(BigDecimal dividend, BigDecimal divisor)
        {
            BigInteger p = dividend.UnscaledValue;
            BigInteger q = divisor.UnscaledValue;
            BigInteger gcd;             // greatest common divisor between 'p' and 'q'
            BigInteger quotient;
            BigInteger remainder;
            long       diffScale = (long)dividend.Scale - divisor.Scale;
            int        newScale;    // the new scale for final quotient
            int        k;           // number of factors "2" in 'q'
            int        l       = 0; // number of factors "5" in 'q'
            int        i       = 1;
            int        lastPow = BigDecimal.FivePow.Length - 1;

            if (divisor.IsZero)
            {
                // math.04=Division by zero
                throw new ArithmeticException(Messages.math04);                 //$NON-NLS-1$
            }
            if (p.Sign == 0)
            {
                return(BigDecimal.GetZeroScaledBy(diffScale));
            }
            // To divide both by the GCD
            gcd = BigMath.Gcd(p, q);
            p   = p / gcd;
            q   = q / gcd;
            // To simplify all "2" factors of q, dividing by 2^k
            k = q.LowestSetBit;
            q = q >> k;
            // To simplify all "5" factors of q, dividing by 5^l
            do
            {
                quotient = BigMath.DivideAndRemainder(q, BigDecimal.FivePow[i], out remainder);
                if (remainder.Sign == 0)
                {
                    l += i;
                    if (i < lastPow)
                    {
                        i++;
                    }
                    q = quotient;
                }
                else
                {
                    if (i == 1)
                    {
                        break;
                    }
                    i = 1;
                }
            } while (true);
            // If  abs(q) != 1  then the quotient is periodic
            if (!BigMath.Abs(q).Equals(BigInteger.One))
            {
                // math.05=Non-terminating decimal expansion; no exact representable decimal result.
                throw new ArithmeticException(Messages.math05);                 //$NON-NLS-1$
            }
            // The sign of the is fixed and the quotient will be saved in 'p'
            if (q.Sign < 0)
            {
                p = -p;
            }
            // Checking if the new scale is out of range
            newScale = BigDecimal.ToIntScale(diffScale + System.Math.Max(k, l));
            // k >= 0  and  l >= 0  implies that  k - l  is in the 32-bit range
            i = k - l;

            p = (i > 0)
                                ? Multiplication.MultiplyByFivePow(p, i)
                                : p << -i;
            return(new BigDecimal(p, newScale));
        }
コード例 #12
0
 /**
  * Tests whether this {@code BigInteger} is probably prime. If {@code true}
  * is returned, then this is prime with a probability beyond
  * (1-1/2^certainty). If {@code false} is returned, then this is definitely
  * composite. If the argument {@code certainty} <= 0, then this method
  * returns true.
  *
  * @param certainty
  *            tolerated primality uncertainty.
  * @return {@code true}, if {@code this} is probably prime, {@code false}
  *         otherwise.
  */
 public static bool IsProbablePrime(BigInteger value, int certainty)
 {
     return(Primality.IsProbablePrime(BigMath.Abs(value), certainty));
 }