Advertisement
Guest User

Untitled

a guest
Oct 19th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Sub primeSieveOfEratosthenes()
  2.    ' Bitmap "p" structure:
  3.   '    If (p(n\60) And fb(n Mod 60)) = 0 then p is prime
  4.   Dim nmax As Double ' size of the sieve; all primes up to nmax will be found.
  5.   Dim nmaxsqrt As Long ' sqrt(nmax)
  6.   Dim nmax60 As Long ' nmax\60
  7.   Dim countPrimes As Long, countPairs As Long
  8.    Dim p() As Integer ' sieve; each 16-bit integer has bits for a group of 60 possible primes
  9.   Dim fb(59) As Integer ' "find bit" array, selects bit of p(n\60) that represents this prime; fb=0,1,0,0,0,0,0,2,...
  10.   Dim ib(15) As Integer ' "index bit" array, indexes to the next nonzero element of fb; ib=1,7,11,13,...,53,59
  11.   Dim fbib(59) As Integer ' fb(ib(i2)); fbib=1,2,4,8,...,-32768
  12.   Dim i As Double, i1 As Long, i2 As Integer, j As Double, j1 As Long, j2 As Long
  13.    Dim sec As Double ' number of seconds it takes me to update the sieve and count all the primes
  14.  
  15.    sec = Timer()
  16.    nmax = Selection.Range("A1").Value ' use a billion for testing, or 179424673, or 2038074743
  17.   nmaxsqrt = Int(Sqr(nmax))
  18.    nmax60 = Int(nmax / 60)
  19.    ReDim p(nmax60)
  20.    ib(0) = 1: ib(1) = 7: ib(2) = 11: ib(3) = 13: ib(4) = 17: ib(5) = 19: ib(6) = 23: ib(7) = 29:
  21.    ib(8) = 31: ib(9) = 37: ib(10) = 41: ib(11) = 43: ib(12) = 47: ib(13) = 49: ib(14) = 53: ib(15) = 59:
  22.    fb(ib(0)) = 1: For i = 1 To 14: fb(ib(i)) = 2 * fb(ib(i - 1)): Next i: fb(ib(i)) = (-2) * fb(ib(i - 1))
  23.    For i = 0 To 15: fbib(i) = fb(ib(i)): Next i
  24.    
  25.    i = 5: ' start off having counted 2, 3, and 5
  26.   i1 = 0: i2 = 0
  27.    Do
  28.       ' Advance i = i1 * 60 + ib(i2) to the next prime
  29.      Do
  30.          For i2 = i2 + 1 To 15
  31.             If (p(i1) And fbib(i2)) = 0 Then Exit Do
  32.          Next i2
  33.          i1 = i1 + 1
  34.          If i1 > nmax60 Then GoTo finish
  35.          i2 = -1
  36.       Loop
  37.       i = i1 * 60 + ib(i2)
  38.       If i > nmaxsqrt Then GoTo finish
  39.       ' knock out multiples of i, starting with i^2
  40.      For j = i ^ 2 To nmax Step 2 * i
  41.          j1 = Int(j / 60)
  42.          'j2 = j - CDbl(j1) * 60
  43.         p(j1) = p(j1) Or fb(j - CDbl(j1) * 60)
  44.       Next j
  45.    Loop
  46. finish:
  47.    countPrimes = 3 'start off having counted 2, 3, and 5
  48.   For i = 5 To nmax Step 2
  49.       i1 = Int(i / 60): i2 = i - CDbl(i1) * 60
  50.       If fb(i2) <> 0 And (fb(i2) And p(i1)) = 0 Then countPrimes = countPrimes + 1
  51.    Next i
  52.    
  53.    countPairs = 0
  54.    i = 3
  55.    j = nmax - i: j1 = Int(j / 60): j2 = j - CDbl(j1) * 60
  56.    If fb(j2) <> 0 And (fb(j2) And p(j1)) = 0 Then countPairs = countPairs + 1
  57.    For i = 5 To Int(nmax / 2) Step 2
  58.       i1 = Int(i / 60): i2 = i - CDbl(i1) * 60
  59.       If fb(i2) <> 0 And (fb(i2) And p(i1)) = 0 Then
  60.          j = nmax - i: j1 = Int(j / 60): j2 = j - CDbl(j1) * 60
  61.          If fb(j2) <> 0 And (fb(j2) And p(j1)) = 0 Then countPairs = countPairs + 1
  62.       End If
  63.    Next i
  64.    
  65.    Selection.Range("A1").Value = nmax
  66.    Selection.Range("B1").Value = countPrimes
  67.    Selection.Range("C1").Value = countPairs
  68.    Selection.Range("D1").Value = Timer() - sec
  69.    Selection.Range("A2").Select
  70. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement