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"); }
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"); } }
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"); }
/** @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)); }
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)); }
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"); }
/** * 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)); }
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("sign", sign); byte[] magn = BigMath.Abs(this).ToByteArray(); info.AddValue("magnitude", magn, typeof(byte[])); }
/** * 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)); }
/** @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)); }
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)); }
/** * 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)); }