Results 1 to 3 of 3

Thread: Generate Primes over 100 Million

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Location
    Amsterdam, NY
    Posts
    85

    Generate Primes over 100 Million

    Hello, I salvaged the following piece of code from:
    http://www.vbforums.com/showpost.php...65&postcount=8

    This code works fine, but the problem comes when I need to get all the primes above 100 million. I am familar (at least a little bit) with the BigInteger class in .NET 4.0, but when I replace all the instances of "Integer" with "BigInteger" in the following code I get this error:
    Value of type 'System.Collections.Generic.List(Of System.Numerics.BigInteger)' cannot be converted to 'System.Collections.Generic.List(Of Integer)'.

    (The reason I need primes above 100 million is that I'm trying to work through some projects on www.projecteuler.net)

    Anyone have some ideas on how to modify the code to work with BigIntegers, Thank you very much for your help. If you need more code examples please ask.

    vb.net Code:
    1. 'Sieve of Eratosthenes
    2.     'http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
    3.     '1. Create a contiguous list of numbers from two to some highest number n.
    4.     '2. Strike out from the list all multiples of two (4, 6, 8 etc.).
    5.     '3. The list's next number that has not been struck out is a prime number.
    6.     '4. Strike out from the list all multiples of the number you identified in the previous step.
    7.     '5. Repeat steps 3 and 4 until you reach a number that is greater than the square root of n (the highest number in the list).
    8.     '6. All the remaining numbers in the list are prime.
    9.     Private Function Sieve_of_Eratosthenes(ByVal MaxNum As Integer) As List(Of Integer)
    10.         'tested to MaxNum = 10,000,000 - on 1.8Ghz Laptop it took 1.4 seconds
    11.         Dim thePrimes As New List(Of Integer)
    12.         Dim toNum As Integer = MaxNum, stpw As New Stopwatch
    13.         If toNum > 1 Then 'the first prime is 2
    14.             stpw.Start()
    15.             thePrimes.Capacity = toNum 'size the list
    16.             Dim idx As Integer
    17.             Dim stopAT As Integer = CInt(Math.Sqrt(toNum) + 1)
    18.             '1. Create a contiguous list of numbers from two to some highest number n.
    19.             '2. Strike out from the list all multiples of 2, 3, 5.
    20.             For idx = 0 To toNum
    21.                 If idx > 5 Then
    22.                     If idx Mod 2 <> 0 _
    23.                     AndAlso idx Mod 3 <> 0 _
    24.                     AndAlso idx Mod 5 <> 0 Then thePrimes.Add(idx) Else thePrimes.Add(-1)
    25.                 Else
    26.                     thePrimes.Add(idx)
    27.                 End If
    28.             Next
    29.             'mark 0,1 and 4 as non-prime
    30.             thePrimes(0) = -1
    31.             thePrimes(1) = -1
    32.             thePrimes(4) = -1
    33.             Dim aPrime, startAT As Integer
    34.             idx = 7 'starting at 7 check for primes and multiples
    35.             Do
    36.                 '3. The list's next number that has not been struck out is a prime number.
    37.                 '4. Strike out from the list all multiples of the number you identified in the previous step.
    38.                 '5. Repeat steps 3 and 4 until you reach a number that is greater than the square root of n (the highest number in the list).
    39.                 If thePrimes(idx) <> -1 Then ' if equal to -1 the number is not a prime
    40.                     'not equal to -1 the number is a prime
    41.                     aPrime = thePrimes(idx)
    42.                     'get rid of multiples
    43.                     startAT = aPrime * aPrime
    44.                     For mltpl As Integer = startAT To thePrimes.Count - 1 Step aPrime
    45.                         If thePrimes(mltpl) <> -1 Then thePrimes(mltpl) = -1
    46.                     Next
    47.                 End If
    48.                 idx += 2 'increment index
    49.             Loop While idx < stopAT
    50.             '6. All the remaining numbers in the list are prime.
    51.             thePrimes = thePrimes.FindAll(Function(i As Integer) i <> -1)
    52.             stpw.Stop()
    53.             Debug.WriteLine(stpw.ElapsedMilliseconds)
    54.         End If
    55.         Return thePrimes
    56.     End Function


    And here is what I changed it to:

    vb.net Code:
    1. Private Function Sieve_of_Eratosthenes(ByVal MaxNum As BigInteger) As List(Of BigInteger)
    2.           'tested to MaxNum = 10,000,000 - on 1.8Ghz Laptop it took 1.4 seconds
    3.           Dim thePrimes As New List(Of BigInteger)
    4.           Dim toNum As BigInteger = MaxNum, stpw As New Stopwatch
    5.           If toNum > 1 Then 'the first prime is 2
    6.                stpw.Start()
    7.                thePrimes.Capacity = toNum 'size the list
    8.                Dim idx As BigInteger
    9.                Dim stopAT As BigInteger = Math.Sqrt(toNum) + 1
    10.                '1. Create a contiguous list of numbers from two to some highest number n.
    11.                '2. Strike out from the list all multiples of 2, 3, 5.
    12.                For idx = 0 To toNum
    13.                     If idx > 5 Then
    14.                          If idx Mod 2 <> 0 _
    15.                          AndAlso idx Mod 3 <> 0 _
    16.                          AndAlso idx Mod 5 <> 0 Then thePrimes.Add(idx) Else thePrimes.Add(-1)
    17.                     Else
    18.                          thePrimes.Add(idx)
    19.                     End If
    20.                Next
    21.                'mark 0,1 and 4 as non-prime
    22.                thePrimes(0) = -1
    23.                thePrimes(1) = -1
    24.                thePrimes(4) = -1
    25.                Dim aPrime, startAT As BigInteger
    26.                idx = 7 'starting at 7 check for primes and multiples
    27.  
    28.                Do
    29.                     '3. The list's next number that has not been struck out is a prime number.
    30.                     '4. Strike out from the list all multiples of the number you identified in the previous step.
    31.                     '5. Repeat steps 3 and 4 until you reach a number that is greater than the square root of n (the highest number in the list).
    32.                     If thePrimes(idx) <> -1 Then ' if equal to -1 the number is not a prime
    33.                          'not equal to -1 the number is a prime
    34.                          aPrime = thePrimes(idx)
    35.                          'get rid of multiples
    36.                          startAT = aPrime * aPrime
    37.                          For mltpl As BigInteger = startAT To thePrimes.Count - 1 Step aPrime
    38.                               If thePrimes(mltpl) <> -1 Then thePrimes(mltpl) = -1
    39.                          Next
    40.                     End If
    41.                     idx += 2 'increment index
    42.                Loop While idx < stopAT
    43.  
    44.                '6. All the remaining numbers in the list are prime.
    45.                thePrimes = thePrimes.FindAll(Function(i As BigInteger) i <> -1)
    46.                stpw.Stop()
    47.                Console.WriteLine(stpw.ElapsedMilliseconds & " milliseconds to generate primes")
    48.           End If
    49.           Return thePrimes
    50.      End Function
    Last edited by patplays852; Jun 27th, 2010 at 08:28 PM.

  2. #2
    Hyperactive Member Philly0494's Avatar
    Join Date
    Apr 2008
    Posts
    485

    Re: Generate Primes over 100 Million

    did you also change the instances of "Integer" to "BigInteger" in line 9?

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Location
    Amsterdam, NY
    Posts
    85

    Re: Generate Primes over 100 Million

    yup, I also updated first post to show what I have (should have done it before but I didn't think of it)

    (at the top I also have)
    vb.net Code:
    1. Imports System.Math
    2. Imports System.Numerics

    Here is a custom class I wrote before finding the above code, it works, but is way too slow.

    vb.net Code:
    1. Class Primes
    2.           Dim LargestNonPrime As ULong = 0 ' Will only generate primes below this number
    3.           Dim primes As New ArrayList         ' Will hold all our primes
    4.           Dim currentprime As Long = -1       ' set to -1 so that you will return the first prime in the array (0) because you have to iterate the currentprime b4 you can return the value
    5.           Dim toRemove As New ArrayList       ' will hold the numbers to remove from our primes array (holds non-primes)
    6.  
    7.  
    8.           Sub Generate(ByVal tempnum As ULong)
    9.                LargestNonPrime = tempnum
    10.                Dim sw As New Stopwatch   'If you want to benchmark, uncomment this and the next line
    11.                sw.Start()
    12.  
    13.                For x As Integer = 0 To LargestNonPrime  ' Creates an arraylist from 0 to the number you specify
    14.                     primes.Add(x)
    15.                Next
    16.  
    17.                For i As Integer = 2 To LargestNonPrime / 2
    18.                     Dim x As BigInteger = BigInteger.Multiply(i, i) ' Replace with Dim x as ulong = i*i if you are not running .NET 4.0 (imports system.numerics is required)
    19.                     While x <= LargestNonPrime
    20.                          toRemove.Add(x) 'adds all numbers that are non-prime into an array for removal
    21.                          x += i
    22.                     End While
    23.                Next
    24.  
    25.                primes.Remove(0) 'manually remove 0 and 1 from the array (IF you count 1 as a prime number, then comment out or remove the next line)
    26.                primes.Remove(1)
    27.  
    28.                toRemove.Sort() 'sorts the array from smallest to largest (when adding items to the array we have a LOT of doubles (when i was testing all primes for 100,000 i had close to .5million items in this array.
    29.  
    30.                'remove doubles from toRemove array
    31.                For i = toRemove.Count - 1 To 1 Step -1
    32.                     If (toRemove(i).ToString() = toRemove(i - 1).ToString()) Then
    33.                          toRemove.RemoveAt(i)
    34.                     End If
    35.                Next
    36.  
    37.                'next 3 lines were used for debugging purposes
    38.                'For x As Integer = 0 To toRemove.Count - 1
    39.                '     Console.WriteLine(toRemove(x).ToString)
    40.                'Next
    41.  
    42.  
    43.                For i As Integer = 0 To toRemove.Count - 1
    44.                     primes.Remove(CInt(toRemove(i).ToString)) 'removes all of the items in the remove array from the array of primes we have going (leaves only primes left)
    45.                     'Console.WriteLine(toRemove.Count.ToString & " left to remove, removing " & toRemove(i).ToString) 'used for debugging purposes
    46.                Next
    47.  
    48.                'rest of the subroutine used for debugging purposes
    49.                sw.stop()
    50.                Console.WriteLine("ran in:  " & sw.ElapsedMilliseconds & "    number of primes:  " & primes.Count)
    51.  
    52.                'For x As Integer = 0 To primes.Count - 1
    53.                '     Console.WriteLine(primes(x).ToString)
    54.                'Next
    55.  
    56.           End Sub
    57.  
    58.           Sub Reset()
    59.                currentprime = -1 'resets our current prime to -1 (so when we call .NextPrime() it will return the first value in the array
    60.           End Sub
    61.  
    62.           Function NumOfPrimes() As ULong
    63.                Return primes.Count ' returns the number of primes we have...
    64.           End Function
    65.  
    66.           Function NextPrime() As ULong
    67.                currentprime += 1 'since we set currentprime = -1 at the beginning and in the .Reset() sub it will add 1 making it equal to 0 and thus return the first item in the array of primes
    68.                Return primes(currentprime)
    69.           End Function
    70.  
    71.      End Class
    Last edited by patplays852; Jun 27th, 2010 at 09:14 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width