internal void FindAllFactors( Integer FindFromNotChanged ) { // ShowStats(); // So far. OriginalFindFrom.Copy( FindFromNotChanged ); FindFrom.Copy( FindFromNotChanged ); NumbersTested++; ClearFactorsArray(); Integer OneFactor; OneFactorRec Rec; // while( not forever ) for( int Count = 0; Count < 1000; Count++ ) { if( Worker.CancellationPending ) return; uint SmallPrime = IntMath.IsDivisibleBySmallPrime( FindFrom ); if( SmallPrime == 0 ) break; // No more small primes. // Worker.ReportProgress( 0, "Found a small prime factor: " + SmallPrime.ToString() ); AddToStats( SmallPrime ); OneFactor = new Integer(); OneFactor.SetFromULong( SmallPrime ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; Rec.IsDefinitelyAPrime = true; AddFactorRec( Rec ); if( FindFrom.IsULong()) { ulong CheckLast = FindFrom.GetAsULong(); if( CheckLast == SmallPrime ) { Worker.ReportProgress( 0, "It only had small prime factors." ); VerifyFactors(); return; // It had only small prime factors. } } IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder ); if( !Remainder.IsZero()) throw( new Exception( "Bug in FindAllFactors. Remainder is not zero." )); FindFrom.Copy( Quotient ); if( FindFrom.IsOne()) throw( new Exception( "Bug in FindAllFactors. This was already checked for 1." )); } // Worker.ReportProgress( 0, "No more small primes." ); if( IsFermatPrimeAdded( FindFrom )) { VerifyFactors(); return; } // while( not forever ) for( int Count = 0; Count < 1000; Count++ ) { if( Worker.CancellationPending ) return; // If FindFrom is a ulong then this will go up to the square root of // FindFrom and return zero if it doesn't find it there. So it can't // go up to the whole value of FindFrom. uint SmallFactor = NumberIsDivisibleByUInt( FindFrom ); if( SmallFactor == 0 ) break; // This is necessarily a prime because it was the smallest one found. AddToStats( SmallFactor ); // Worker.ReportProgress( 0, "Found a small factor: " + SmallFactor.ToString( "N0" )); OneFactor = new Integer(); OneFactor.SetFromULong( SmallFactor ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; Rec.IsDefinitelyAPrime = true; // The smallest factor. It is necessarily a prime. AddFactorRec( Rec ); IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder ); if( !Remainder.IsZero()) throw( new Exception( "Bug in FindAllFactors. Remainder is not zero. Second part." )); if( Quotient.IsOne()) throw( new Exception( "This can't happen here. It can't go that high." )); FindFrom.Copy( Quotient ); if( IsFermatPrimeAdded( FindFrom )) { VerifyFactors(); return; } } if( IsFermatPrimeAdded( FindFrom )) { VerifyFactors(); return; } // If it got this far then it's definitely composite or definitely // small enough to factor. Integer P = new Integer(); Integer Q = new Integer(); bool TestedAllTheWay = FindTwoFactorsWithFermat( FindFrom, P, Q, 0 ); if( !P.IsZero()) { // Q is necessarily prime because it's bigger than the square root. // But P is not necessarily prime. // P is the smaller one, so add it first. if( IsFermatPrimeAdded( P )) { Worker.ReportProgress( 0, "P from Fermat method was probably a prime." ); } else { OneFactor = new Integer(); OneFactor.Copy( P ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; Rec.IsDefinitelyNotAPrime = true; AddFactorRec( Rec ); } Worker.ReportProgress( 0, "Q is necessarily prime." ); OneFactor = new Integer(); OneFactor.Copy( Q ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; Rec.IsDefinitelyAPrime = true; AddFactorRec( Rec ); } else { // Didn't find any with Fermat. OneFactor = new Integer(); OneFactor.Copy( FindFrom ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; if( TestedAllTheWay ) Rec.IsDefinitelyAPrime = true; else Rec.IsDefinitelyNotAPrime = true; AddFactorRec( Rec ); } Worker.ReportProgress( 0, "That's all it could find." ); VerifyFactors(); }
private void AddFactorRec( OneFactorRec Rec ) { // if( Rec == null ) // return false; FactorsArray[FactorsArrayLast] = Rec; SortIndexArray[FactorsArrayLast] = FactorsArrayLast; FactorsArrayLast++; if( FactorsArrayLast >= FactorsArray.Length ) { try { Array.Resize( ref FactorsArray, FactorsArray.Length + 16 ); Array.Resize( ref SortIndexArray, FactorsArray.Length ); } catch( Exception Except ) { throw( new Exception( "Couldn't resize the arrays for FindFactors.cs. " + Except.Message )); } } }
private bool IsFermatPrimeAdded( Integer FindFrom ) { if( FindFrom.IsULong()) { // The biggest size that NumberIsDivisibleByUInt() will check to // see if it has primes for sure. if( FindFrom.GetAsULong() < (223092870UL * 223092870UL)) return false; // Factor this. } int HowManyTimes = 20; // How many primes it will be checked with. if( !IntMath.IsFermatPrime( FindFrom, HowManyTimes )) return false; Integer OneFactor = new Integer(); OneFactor.Copy( FindFrom ); OneFactorRec Rec = new OneFactorRec(); Rec.Factor = OneFactor; // Neither one of these is set to true here because it's probably // a prime, but not definitely. // Rec.IsDefinitelyAPrime = false; // Rec.IsDefinitelyNotAPrime = false; AddFactorRec( Rec ); Worker.ReportProgress( 0, "Fermat thinks this one is a prime." ); return true; // It's a Fermat prime and it was added. }
internal void FindSmallPrimeFactorsOnly( Integer FindFromNotChanged ) { OriginalFindFrom.Copy( FindFromNotChanged ); FindFrom.Copy( FindFromNotChanged ); ClearFactorsArray(); Integer OneFactor; OneFactorRec Rec; // while( not forever ) for( int Count = 0; Count < 1000; Count++ ) { if( Worker.CancellationPending ) return; uint SmallPrime = IntMath.IsDivisibleBySmallPrime( FindFrom ); if( SmallPrime == 0 ) break; // No more small primes. // Worker.ReportProgress( 0, "Found a small prime factor: " + SmallPrime.ToString() ); OneFactor = new Integer(); OneFactor.SetFromULong( SmallPrime ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; Rec.IsDefinitelyAPrime = true; AddFactorRec( Rec ); if( FindFrom.IsULong()) { ulong CheckLast = FindFrom.GetAsULong(); if( CheckLast == SmallPrime ) { // Worker.ReportProgress( 0, "It only had small prime factors." ); VerifyFactors(); return; // It had only small prime factors. } } IntMath.Divide( FindFrom, OneFactor, Quotient, Remainder ); if( !Remainder.IsZero()) throw( new Exception( "Bug in FindSmallPrimeFactorsOnly(). Remainder is not zero." )); FindFrom.Copy( Quotient ); if( FindFrom.IsOne()) throw( new Exception( "Bug in FindSmallPrimeFactorsOnly(). This was already checked for 1." )); } // Worker.ReportProgress( 0, "One factor was not a small prime." ); OneFactor = new Integer(); OneFactor.Copy( FindFrom ); Rec = new OneFactorRec(); Rec.Factor = OneFactor; AddFactorRec( Rec ); // Worker.ReportProgress( 0, "No more small primes." ); }