以往的質數篩都採用除篩法,通過逐個測試 對 的可除性來確認一個數是不是質數。
衆所周知,計算機除法是一系列減法的組合,運算速度較慢。
當計算機具有足夠大的內存時,可以採用乘篩法,方法是先定義一個一維旗標數組,當做一條有限長的紙帶,下標 的每個元素對應一個自然數的狀態,從開始逐個篩去因數的倍數,將被篩數所在的旗標置1(打孔),表示已經被驗證爲合數,直到因數 全部被篩完,這時紙帶上未被打孔的就是質數。然後枚舉旗標數組,將未被標記爲合數的數字作爲質數顯示出來,例如:
2 | 3 | 5 | 7 | 11 | 13 |
(未完待續)
#INCLUDE "VBCOMPAT.BI"
'定義紙帶長度
CONST PAPER_LEN AS INTEGER = 121
'定義合數指示旗標
DIM FLAG() AS INTEGER
DIM FLAG_TMP() AS INTEGER
'定義循環變量
DIM I AS INTEGER
DIM J AS INTEGER
DIM N AS INTEGER
DIM A AS DOUBLE
DIM B AS DOUBLE
DIM K AS INTEGER
REDIM FLAG(PAPER_LEN * 2 + 1)
REDIM FLAG_TMP(PAPER_LEN * 2 + 1)
'劃掉第一個數
FLAG(1) = 1
N = PAPER_LEN
PRINT "PRIME v0.01"
PRINT "PAPER_LEN = "; N
PRINT "SQR(N) = "; SQR(N)
A = NOW
PRINT "BEGIN = "; FORMAT(A, "yy/mm/dd hh:mm:ss")
'劃掉偶數
J = 2
I = 2
K = 1
DO WHILE I < N
I = I + J
FLAG(I) = 1
K = K + 1
LOOP
FOR I=3 TO SQR(N) STEP 2
IF FLAG(I) = 0 THEN
FOR J=I TO N/I STEP 2
IF FLAG(J) = 0 THEN
FLAG_TMP(I*J) = 1
K = K + 1
END IF
NEXT J
FOR J=I TO N STEP 2
IF FLAG_TMP(J) = 1 THEN
FLAG(J) = 1 : FLAG_TMP(J) = 0
END IF
NEXT J
END IF
NEXT I
FOR I=1 TO N
IF FLAG(I) = 0 THEN
PRINT I,
END IF
NEXT I
B = NOW
PRINT "OPERATIONS = "; K
PRINT "END = "; FORMAT(B, "yy/mm/dd hh:mm:ss")
END