Onko joku luku alkuluku vai ei, voidaan selvittää helposti jakamalla kaikilla lukua pienemmillä luvuilla. Jos jokin jakojäännös on nolla niin ei ole alkuluku. Testi tarvitsee toistaa vain luvuille 2... neliöjuuri ko. luvusta.
Todella suurilla luvuilla tämä testaus tapa hyytyy mahdottomuuteensa. Avuksi tulee Fermat'n pieni teoreema:
jos k^(A-1) mod A ei ole 1 niin A ei ole alkuluku
Toistamalla testi riittävän usealla k:n arvolla saadaan riittävällä todennäköisyydellä tietää onko suuri luku alkuluku (=todennäköinen alkuluku).
Oheinen ohjelma demoaa testiä. k:n arvot on otettu 100sta ensimmäisestä alkuluvusta. Suurin kelpaava luku on 281474976710676 ja siitä alaspäin. Vauhtia tulee 4000 ... 5000 lukua sekunnissa (ADM 1.66 GHz).
Tee: textbox1,2,3 ja buttonit 1 ja 2
Itse algoritmi
Private Function TestIfPrime(ByVal A As Long) As Boolean
'Fermat's little theorem
' if k^(A-1) mod A is not 1 then A is not a prime
Dim i As Integer
'check small primes
If ((A Mod 2) = 0) And A <> 2 Then
TestIfPrime = False
Exit Function
End If
For i = 3 To 13 Step 2
If ((A Mod i) = 0) And A <> i Then
TestIfPrime = False
Exit Function
End If
Next i
'first 100 prime numbers as k's
Dim pri() As Long = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541}
Dim P As Long
Dim c As Integer = UBound(pri)
P = A - 1
For i = 1 To c
If A = pri(i) Then
TestIfPrime = True
Exit Function
End If
If Power_mod_N(pri(i), P, A) <> 1 Then
TestIfPrime = False
Exit Function
End If
Next i
TestIfPrime = True
End FunctionOhjelma potenssin jäköjäännöksen laskuun
Private Function Power_mod_N(ByVal P As Long, ByVal d As Long, ByVal n As Long) As Long
'A = (P ^ D) Mod N , P must be less than N
'A = (P^e2 * P^e2 * P^e3) Mod N where D= 2*e2+e3 , e3 is 1 or 0
'A = ((P^e2)mod N) * ((P^e2)mod N)) * ((P^e3)mod N))Mod N
'then recursive call untill exponent is one
' because P<N then P^1 mod N = P
Dim e2 As Long
Dim e3 As Long
Dim a2 As Long
Dim a3 As Long
Dim a4 As Decimal
Dim a5 As Decimal
Dim a6 As Decimal
e2 = d \ 2
e3 = d - 2 * e2
If e2 = 1 Then 'recursion ends
a2 = P
Else
a2 = Power_mod_N(P, e2, n) 'recursion continues
End If
If e3 = 1 Then
a3 = P 'a3=P when e3=1
Else
a3 = 1 ' P^0
End If
'A= (a2*a2*a3) mod N
'A=((a2*a2)mod n * a3 )mod n
a6 = CDec(a2) ' convert to decimal
a4 = a6 * a6
a5 = a4 Mod CDec(n)
a4 = a5 * CDec(a3)
Power_mod_N = CLng(a4 Mod CDec(n))
End FunctionTestinapit
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'pienimmästä ylöspäin
Dim i As Long
Dim count As Long = 1
Dim ts As TimeSpan
Dim t1 As Date
Dim t2 As Date
TextBox1.Text = "Alhaalta ylös 100 000 lukua"
TextBox3.Text = ""
t2 = Now
For i = 3 To 100000 Step 2
If TestIfPrime(i) Then
count = count + 1
TextBox2.Text = CStr(count)
Application.DoEvents()
End If
Next i
t1 = Now
ts = t1.Subtract(t2)
TextBox3.Text = CStr(Int(i / ts.TotalSeconds)) + " lukua sekunnissa"
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'suurimmasta alaspäin testi
Dim i As Long
Dim count As Long = 1
Dim ts As TimeSpan
Dim t1 As Date
Dim t2 As Date
Dim m As Long
TextBox1.Text = "Ylhäältä alas 100 000 lukua"
TextBox3.Text = ""
t2 = Now
For i = 2 To 100000 Step 2
m = 281474976710677 - CLng(i) 'suurimmasta alaspäin
If TestIfPrime(m) Then
count = count + 1
TextBox2.Text = CStr(count)
End If
Application.DoEvents()
Next i
t1 = Now
ts = t1.Subtract(t2)
TextBox3.Text = CStr(Int(i / ts.TotalSeconds)) + " lukua sekunnissa"
End Sub"ADM 1.66 GHz" :D mulla on ainaki amd... :D
Mikähän toi soodan "kommentin" pointti? :P
Tuossa on listattuja alkulukuja, mutta luku 0 ei ole alkuluku...
johan on tehty vaikeasti
Toimihan se, mutta en älyä mitän.
Tarkoitan miten.
"jos k^(A-1) mod A ei ole 1 niin A ei ole alkuluku"
Tämä on väärin. Esimerkiksi 2^(2-1) = 0 mod 2 vaikka 2 on alkuluku. Pitäisi olla muodossa "Jos k^(A-1) mod A ei ole 1 ja k ei ole jaollinen A:lla, niin A ei ole alkuluku."
Ei kaksi voi olla alkuluku, koska sen voi jakaa 2:lla jolloin saa arvon 1 (1, 3 .. jne ovat)
PekkaJari kirjoitti:
Ei kaksi voi olla alkuluku, koska sen voi jakaa 2:lla jolloin saa arvon 1 (1, 3 .. jne ovat)
Alkuluvun määritelmän mukaan luku saa olla jaollinen vain itsellään ja luvulla 1. Luku 2 täyttää molemmat ehdot hyvin. Tämän määritelmän mukaan luku 2 on kyllä alkuluku.
Aihe on jo aika vanha, joten et voi enää vastata siihen.