Ich präsentiere stolz, der Primzahltest mit Testcode. \^-^/ Ich kann kaum glauben, dass es wirklich funktioniert O_o. Vielen Danke Stargate :* :P.
Wenn jemand einen Fehler findet, oder Verbesserungsvorschläge hat, bitte ich darum.
Code: Alles auswählen
XIncludeFile "UnlimitedIntegerArithmetic.dll.pbi"
EnableExplicit
Define Private.Z
Define Jawohl
Procedure CreateNumber(*Number.Z)
  ;Protected Number.Z
  Protected n
  Protected NumberString.s
 
  If Not OpenCryptRandom()
    ProcedureReturn 0
  EndIf
 
  For n = 1 To 10
    NumberString.s + Str(CryptRandom(10))
  Next
  CloseCryptRandom()
  Z_Number(*Number,NumberString)
  ProcedureReturn *Number
EndProcedure
Procedure ISPrime(*Number.Z,Accuracy.f)
  ;Pretest
  Protected Number.Z
  Protected.s NumberString = Z_String(*Number)
  Protected.s LastNumber = Right(NumberString,1)
  Protected NumberStringSize = Len(NumberString)
  Protected Quersumme
  Protected n
  Protected A.Z
  Protected ARandomMax.Z
  Protected Zero.Z
  Protected One.Z
  Protected Two.Z
  Protected Three.Z
  Protected T.Z
  Protected Alpha.Z
  Protected TMod.Z
  Protected k
  Protected P.Z
  Protected.b Prim = #False
  Protected NumberMinusOne.Z
  Protected PModN.Z
  Protected kmax
  
  kmax = Round(Log(1-Accuracy)/Log(1/4),#PB_Round_Up)
  ;Debug NumberString
  ;Debug LastNumber
  
  If  LastNumber = "2"                                       ;Letzte Zahl 2
    If NumberString = "2"                             ;Nur 2
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
  EndIf
  
  If LastNumber = "0" Or LastNumber = "4" Or LastNumber = "6" Or LastNumber = "8"   ; Gerade
    ProcedureReturn 0
  EndIf
  
  For n = 1 To NumberStringSize
    Quersumme + Val(Mid(NumberString,n,1))
  Next
  
  If Mod(Quersumme,3) = 0         ;Quersumme durch 3 Teilbar ==> Keine Primzahl
    If NumberString = "3"
      ProcedureReturn 1         ;Nur 3
    Else
      ProcedureReturn 0
    EndIf
  EndIf
  
  If LastNumber = "5"            ;Durch 5 Teilbar (0 wird nicht berücksichtigt, da es schon bei "gerade" dabei ist)
    If NumberString = "5"
      ProcedureReturn 1        ;Nur 5
    Else
      ProcedureReturn 0
    EndIf
  EndIf
  ;Eigentlicher Test
  Z_Set(Zero,0)
  Z_Set(One,1)
  Z_Set(Two,2)
  Z_String(Two)
  Z_Set(Three,3)
  Z_Copy(ARandomMax,*Number)
  Z_Copy(T,*Number)
  Z_subtract(ARandomMax,Three)
  Z_Subtract(T,One)
  Z_Copy(NumberMinusOne,*Number)
  Z_Subtract(NumberMinusOne,One)
  
  For k = 0 To kmax
    Z_Random(A,ARandomMax)          ;2 <= A <= Number - 1
    Z_Add(A,Two)
    
    Z_Zero(Alpha)
    Z_copy(Tmod,T)
    Z_Modulo(Tmod,Two)
    While Z_Compare(Tmod,Zero) = #Z_Equal
      Z_Divide(T,Two)
      Z_add(Alpha,One)
      Z_Copy(Tmod,T)
      Z_Modulo(Tmod,Two)
    Wend
    Z_Copy(P,A)
    Z_PowerModulo(P,T,*Number)
    Prim = #False
    Z_subtract(Alpha,One)
    If Z_Compare(P,NumberMinusOne) = #Z_Equal Or Z_Compare(P,One) = #Z_Equal
      Prim = #True
    EndIf
    While Prim = #False And Z_Compare(Alpha,Zero) = #Z_Greater And Z_Compare(P,One) = #Z_Greater
      Z_copy(PModN,P)
      Z_modulo(P,*Number)
      Z_Multiply(P,PModN)
      Z_subtract(Alpha,One)
      If Z_Compare(P,NumberMinusOne) = #Z_Equal
        Prim = #True
      EndIf
    Wend
    If Prim = #False
      ProcedureReturn 0
    EndIf
  Next
  ProcedureReturn 1
EndProcedure
Repeat
  CreateNumber(Private)
Jawohl = ISPrime(Private,0.999999)
Debug "Prime = " + Str(Jawohl) 
Debug "Number = " + Z_String(Private)
Until Jawohl = 1