public static void InvertTo(this PoweredPrime[] factors, List <PoweredPrime> inverted) { for (int i = 0; i < factors.Length; i++) { PoweredPrime factor = factors[i]; inverted.Add(new PoweredPrime(factor.prime, (SByte)(-factor.power))); } }
public FactoredRational(Rational rational, IPrimeFactorizer factorizer) { if (rational.numerator == 0 || rational.denominator == 0) { this.numerator = rational.numerator; this.denominator = rational.denominator; this.primeFactors = PoweredPrime.None; } else { // // Take the absolute value of the rational // PoweredPrime[] denominatorFactors = factorizer.PrimeFactorize(rational.denominator); if (denominatorFactors == null) { throw factorizer.UnableToFactorize(rational.denominator); } UInt32 numeratorAbsoluteValue = (UInt32)((rational.numerator >= 0) ? rational.numerator : -rational.numerator); this.primeFactors = factorizer.Divide(numeratorAbsoluteValue, denominatorFactors); if (this.primeFactors == null) { throw factorizer.UnableToDivide(numeratorAbsoluteValue, denominatorFactors); } // Get new numerator and denominator this.numerator = 1; this.denominator = 1; for (int i = 0; i < this.primeFactors.Length; i++) { PoweredPrime factor = this.primeFactors[i]; if (factor.power > 0) { numerator *= (Int32)factor.value; // I don't need to check overflow here because these factors came from an Int32 } else { denominator *= factor.value; // I don't need to check overflow here because these factors came from a UInt32 } } if (rational.numerator < 0) { numerator = -numerator; } } }
public static void BruteFoce(UInt32 value, List <PoweredPrime> sortedPrimeFactors) { if (value < 2) { return; } PrimeTableEnumerator primeEnumerator = new PrimeTableEnumerator(1); UInt32 currentPrime = 2; SByte currentPrimePower = 0; while (true) { if (value % currentPrime == 0) { if (currentPrimePower >= SByte.MaxValue) { throw new OverflowException(String.Format("Value had a prime factor of {0} with a power greate than 127", currentPrime)); } currentPrimePower++; // // Divide the value and check if it is done being factored // value = value / currentPrime; if (value == 1) { PoweredPrime poweredPrime = new PoweredPrime(currentPrime, currentPrimePower); sortedPrimeFactors.Add(poweredPrime); return; } } else { if (currentPrimePower > 0) { PoweredPrime poweredPrime = new PoweredPrime(currentPrime, currentPrimePower); sortedPrimeFactors.Add(poweredPrime); } // // Get the next prime // currentPrime = primeEnumerator.Next(); currentPrimePower = 0; } } }
public void TestPrimeFactorsInvertTo() { PoweredPrime[] factors; List <PoweredPrime> factorList = new List <PoweredPrime>(); factors = PoweredPrime.None; factors.InvertTo(factorList); Assert.AreEqual(0, factorList.Count); // // 2^1 // factors = new PoweredPrime[] { new PoweredPrime(2, 1) }; factorList.Clear(); factors.InvertTo(factorList); Assert.AreEqual(1, factorList.Count); Assert.AreEqual(2U, factorList[0].prime); Assert.AreEqual((SByte)(-1), factorList[0].power); // // 2^-1 // factors = new PoweredPrime[] { new PoweredPrime(2, -1) }; factorList.Clear(); factors.InvertTo(factorList); Assert.AreEqual(1, factorList.Count); Assert.AreEqual(2U, factorList[0].prime); Assert.AreEqual((SByte)(1), factorList[0].power); // // (2^120)(3^-80)(19^65) // factors = new PoweredPrime[] { new PoweredPrime(2, 12), new PoweredPrime(3, -8), new PoweredPrime(19, 6) }; factorList.Clear(); factors.InvertTo(factorList); Assert.AreEqual(3, factorList.Count); Assert.AreEqual(2U, factorList[0].prime); Assert.AreEqual((SByte)(-12), factorList[0].power); Assert.AreEqual(3U, factorList[1].prime); Assert.AreEqual((SByte)(8), factorList[1].power); Assert.AreEqual(19U, factorList[2].prime); Assert.AreEqual((SByte)(-6), factorList[2].power); }
public static void DivideInto(this PoweredPrime[] divideFactors, List <PoweredPrime> factors) { if (divideFactors.Length <= 0) { return; } int factorIndex = 0; int divideIndex = 0; PoweredPrime currentDivideFactor = divideFactors[0]; while (factorIndex < factors.Count) { PoweredPrime currentFactor = factors[factorIndex]; if (currentDivideFactor.prime < currentFactor.prime) { factors.Insert(factorIndex, new PoweredPrime(currentDivideFactor.prime, (SByte)(-currentDivideFactor.power))); divideIndex++; if (divideIndex >= divideFactors.Length) { return; } currentDivideFactor = divideFactors[divideIndex]; } else if (currentDivideFactor.prime == currentFactor.prime) { Int32 powerDifference = (Int32)currentFactor.power - (Int32)currentDivideFactor.power; if (powerDifference == 0) { factors.RemoveAt(factorIndex); } else { if (powerDifference < SByte.MinValue || powerDifference > SByte.MaxValue) { throw new InvalidOperationException(String.Format( "Cannot perform division because the difference of powers for factor {0} is out of range ({1} - {2} = {3})", currentFactor.prime, currentFactor.power, currentDivideFactor.power, powerDifference)); } factors[factorIndex] = new PoweredPrime(currentFactor.prime, (SByte)powerDifference); factorIndex++; } divideIndex++; if (divideIndex >= divideFactors.Length) { return; } currentDivideFactor = divideFactors[divideIndex]; } else { factorIndex++; } } // Add the rest of the divide factors while (true) { factors.Add(new PoweredPrime(currentDivideFactor.prime, (SByte)(-currentDivideFactor.power))); divideIndex++; if (divideIndex >= divideFactors.Length) { return; } currentDivideFactor = divideFactors[divideIndex]; } }