Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        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 ));
            }
              }
        }
Ejemplo n.º 3
0
        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.
        }
Ejemplo n.º 4
0
        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." );
        }