public static HNumber DivRem(HNumber left, HNumber right, out HNumber remainder) { //Remainder = Numerator - Quotient x Denominator if (right.IsZero) { throw new DivideByZeroException("The Divisor is zero"); } int precision = Math.Max(left.Precision, right.Precision); #region Division Again But with higher precision HNumber tmpLeft = left; int digitDiff = tmpLeft.Precision - (tmpLeft.DigitCount - right.DigitCount); digitDiff = Math.Max(0, digitDiff); tmpLeft.Mantissa *= BigInteger.Pow(10, digitDiff); tmpLeft.Truncate(tmpLeft.DigitCount + tmpLeft.Exponent); BigInteger mantissa = BigInteger.Divide(tmpLeft.Mantissa, right.Mantissa); int exponent = tmpLeft.Exponent - right.Exponent - digitDiff; HNumber quotient = new HNumber(mantissa, exponent, CalculateDigitCount(mantissa), RoundingMode.PrecisionInt); #endregion HNumber qd = Multiply(quotient, right, PrecisionMode.KeepPrecision); remainder = Subtract(left, qd); remainder.Precision = precision; remainder.Round(RoundingMode.PrecisionInt); return(quotient); }
public static HNumber Abs(HNumber value) { if (value.Mantissa < 0) { value.Mantissa *= -1; } return(value); }
public static HNumber Pow(HNumber value, int exponent) { if (exponent < 0) { throw new ArgumentOutOfRangeException(); } BigInteger mantissa = BigInteger.Pow(value.Mantissa, exponent); int exp = value.Exponent * exponent; return(new HNumber(mantissa, exp)); }
public static bool TryParse(string value, out HNumber result) { try { result = Parse(value); } catch (Exception) { result = HNumber.Zero; return(false); } return(true); }
static void ParseTest() { string num1Str = "8e54695"; string num2Str = "123456e-5"; HNumber num1 = HNumber.Parse(num1Str); HNumber num2 = HNumber.Parse(num2Str); Console.WriteLine("HugeInt Parsing {0}, result = {1}", num1Str, num1); Console.WriteLine("BigInteger Parsing {0}, result = {1}", num2Str, num2); Console.WriteLine(); }
public static HNumber GreatestCommonDivisor(HNumber left, HNumber right) { left = Abs(left); right = Abs(right); HNumber a = Max(left, right); HNumber b = Min(left, right); HNumber rem; while (true) { rem = Remainder(a, b); if (rem == 0) { return(b); } a = b; b = rem; } }
public static HNumber Add(HNumber left, HNumber right, PrecisionMode precisionMode = PrecisionMode.UseHigher) { int precision = DEFAULT_PRECISION; if (precisionMode == PrecisionMode.UseHigher) { precision = Math.Max(left.Precision, right.Precision); } else if (precisionMode == PrecisionMode.UseLesser) { precision = Math.Min(left.Precision, right.Precision); } //TODO: ONLY WHEN SEMI ACCURATE RESULTS ARE REQUIRED int digitsTotal = left.DigitCount + right.DigitCount; left.Precision = digitsTotal; right.Precision = digitsTotal; left.Round(RoundingMode.PrecisionInt); right.Round(RoundingMode.PrecisionInt); if (left.Exponent < right.Exponent) { left.Truncate(left.DigitCount - (right.Exponent - left.Exponent)); } else if (left.Exponent > right.Exponent) { right.Truncate(right.DigitCount - (left.Exponent - right.Exponent)); } BigInteger mantissa = left.Mantissa + right.Mantissa; int exponent = Math.Max(left.Exponent, right.Exponent); if (precisionMode == PrecisionMode.KeepPrecision) { precision = CalculateDigitCount(mantissa); } HNumber result = new HNumber(mantissa, exponent, precision); return(result); }
public static HNumber ModPow(HNumber value, HNumber exponent, HNumber modulus) { if (modulus == 1) { return(0); } HNumber curPow = value % modulus; HNumber res = 1; while (exponent > 0) { if (exponent % 2 == 1) { res = (res * curPow) % modulus; } exponent = exponent / 2; curPow = (curPow * curPow) % modulus; } return(res); }
public static int Compare(HNumber left, HNumber right) { if (left.Sign > right.Sign) { return(1); } else if (left.Sign < right.Sign) { return(-1); } int leftTheoreticalExponent = left.Exponent + left.DigitCount; int rightTheoreticalExponent = right.Exponent + right.DigitCount; if (leftTheoreticalExponent == rightTheoreticalExponent) { return(BigInteger.Compare(left.Mantissa, right.Mantissa)); } else { return((leftTheoreticalExponent * left.Sign) > (rightTheoreticalExponent * right.Sign) ? 1 : -1); } }
public static HNumber Multiply(HNumber left, HNumber right, PrecisionMode precisionMode = PrecisionMode.UseHigher) { int precision = DEFAULT_PRECISION; if (precisionMode == PrecisionMode.UseHigher) { precision = Math.Max(left.Precision, right.Precision); } else if (precisionMode == PrecisionMode.UseLesser) { precision = Math.Min(left.Precision, right.Precision); } BigInteger mantissa = left.Mantissa * right.Mantissa; int exponent = left.Exponent + right.Exponent; if (precisionMode == PrecisionMode.KeepPrecision) { precision = CalculateDigitCount(mantissa); } HNumber result = new HNumber(mantissa, exponent, precision); return(result); }
public static HNumber Divide(HNumber left, HNumber right, PrecisionMode precisionMode = PrecisionMode.UseHigher) { int precision = DEFAULT_PRECISION; if (precisionMode == PrecisionMode.UseHigher) { precision = Math.Max(left.Precision, right.Precision); } else if (precisionMode == PrecisionMode.UseLesser) { precision = Math.Min(left.Precision, right.Precision); } if (right.IsZero) { throw new DivideByZeroException("The Divisor is zero"); } int digitDiff = left.Precision - (left.DigitCount - right.DigitCount); digitDiff = Math.Max(0, digitDiff); left.Mantissa *= BigInteger.Pow(10, digitDiff); left.Truncate(left.DigitCount + left.Exponent); BigInteger mantissa = BigInteger.Divide(left.Mantissa, right.Mantissa); int exponent = left.Exponent - right.Exponent - digitDiff; if (precisionMode == PrecisionMode.KeepPrecision) { precision = CalculateDigitCount(mantissa); } HNumber result = new HNumber(mantissa, exponent, precision); return(result); }
public int CompareTo(object obj) { HNumber other = (HNumber)obj; return(Compare(this, other)); }
public int CompareTo(HNumber other) { return(Compare(this, other)); }
public static HNumber Min(HNumber left, HNumber right) { return(Compare(left, right) == -1 ? left : right); }
public static HNumber Negate(HNumber value) { return(new HNumber(-value.Mantissa, value.Exponent)); }
public override bool Equals(object obj) { HNumber other = (HNumber)obj; return(Compare(this, other) == 0); }
public bool Equals(HNumber other) { return(Compare(this, other) == 0); }
public static double Log(HNumber value, double baseValue) { return(BigInteger.Log(value.Mantissa, baseValue) + (value.Exponent * Math.Log(10, baseValue))); }
static void BigIntegerCompareTest() { Random rdm = new Random(1); for (int i = 0; i < 1; i++) { int sign1 = rdm.Next() % 2 == 0 ? 1 : -1; int sign2 = rdm.Next() % 2 == 0 ? 1 : -1; double value1 = 12500; double value2 = 11300; int exp1 = 20; int exp2 = 0; //double value1 = rdm.Next() * sign1; //double value2 = rdm.Next() * sign2; //int exp1 = rdm.Next() % 100; //int exp2 = rdm.Next() % 100; HNumber huge1 = new HNumber(value1, exp1); HNumber huge2 = new HNumber(value2, exp2); BigInteger big1 = new BigInteger(value1); BigInteger big2 = new BigInteger(value2); big1 *= BigInteger.Pow(10, exp1); big2 *= BigInteger.Pow(10, exp2); //Console.WriteLine("HugeInt"); //Console.WriteLine("Value1: {0} , Value2: {1}", huge1, huge2); //Console.WriteLine("BigInt"); //Console.WriteLine("Value1: {0} , Value2: {1}", big1, big2); //Console.WriteLine(); HNumber remainder1 = huge1 % huge2; BigInteger remainder2 = big1 % big2; HNumber quotient1 = huge1 / huge2; BigInteger quotient2 = big1 / big2; HNumber mul1 = huge1 * huge2; BigInteger mul2 = big1 * big2; HNumber add1 = huge1 + huge2; BigInteger add2 = big1 + big2; HNumber sub1 = huge1 - huge2; BigInteger sub2 = big1 - big2; //HNumber gcd1 = HNumber.GreatestCommonDivisor(huge1, huge2); //BigInteger gcd2 = BigInteger.GreatestCommonDivisor(big1, big2); Console.WriteLine("HugeInt Remainder: "); Console.WriteLine("{0} % {1} = {2}", huge1, huge2, remainder1); Console.WriteLine("BigInteger Remainder: "); Console.WriteLine("{0} % {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(remainder2, 0, remainder1.DigitCount + 2)); Console.WriteLine(); Console.WriteLine("HugeInt Divide: "); Console.WriteLine("{0} / {1} = {2}", huge1, huge2, quotient1); Console.WriteLine("BigInt Divide: "); Console.WriteLine("{0} / {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(quotient2, 0, quotient1.DigitCount + 2)); Console.WriteLine(); Console.WriteLine("HugeInt Multiply: "); Console.WriteLine("{0} * {1} = {2}", huge1, huge2, mul1); Console.WriteLine("BigInt Divide: "); Console.WriteLine("{0} * {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(mul2, 0, mul1.DigitCount + 2)); Console.WriteLine(); Console.WriteLine("HugeInt Add: "); Console.WriteLine("{0} + {1} = {2}", huge1, huge2, add1); Console.WriteLine("BigInt Add: "); Console.WriteLine("{0} + {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(add2, 0, add1.DigitCount + 2)); Console.WriteLine(); Console.WriteLine("HugeInt Subtract: "); Console.WriteLine("{0} - {1} = {2}", huge1, huge2, sub1); Console.WriteLine("BigInt Subtract: "); Console.WriteLine("{0} - {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(sub2, 0, sub1.DigitCount + 2)); Console.WriteLine(); //Console.WriteLine("HugeInt GCD: "); //Console.WriteLine("{0} {1} = {2}", huge1, huge2, gcd1); //Console.WriteLine("BigInt GCD: "); //Console.WriteLine("{0} {1} = {2}", new HNumber(big1, 0, 10), new HNumber(big2, 0, 10), new HNumber(gcd2, 0, gcd1.DigitCount+2)); //Console.WriteLine(); Console.WriteLine("------"); } }
public static double Log10(HNumber value) { return(BigInteger.Log10(value.Mantissa) + (value.Exponent * Math.Log10(10))); }