2010-12-05 7 views
0

Alle,Stackoverflow Ausnahme beim Testen Miller Rabin

ich einen Code implementiert haben, die zwei zufällige Primzahlen und die Multiplikation dieser zwei Zahlen erzeugt sollte die Miller Rabin Primzahltest. Allerdings läuft mein Code die ganze Zeit über, während er versucht, eine Nummer zu finden, die den Miller-Rabintest besteht und mit einer Stackoverflow-Ausnahme endet. Hier ist der Code:

private void populateRandomPrimes() 
{ 
    onePrimeValue = RandomPrime.getValue(); 

    do 
    { 
     secondPrimeValue= RandomPrime.getValue(); 
    }while(onePrimeValue == secondPrimeValue); 

    BigInteger calcNum = new BigInteger(Integer.toString(onePrimeValue*secondPrimeValue)); 

    try 
    { 
     **if (calcNum.isProbablePrime(20))** 
      populateMultiplicativeForPlayer(); 
     else 
      populateRandomPrimes(); 
    } 
    catch (Exception io) 
    { 
     io.printStackTrace(); 
    } 
} 

In dem obigen Code:
1> RandomPrime Klasse gibt eine Zufalls prime Zahl
2> Sowohl onePrimeValue und secondPrimeValue sollte verschiedene
3 sein> Da der Code Linie: if (calcNum.isProbablePrime(20)) gibt nie eine true, ich am Ende die gleiche aufrufen, bis ich Stackoverflow Ausnahme

kann mir jemand vorschlagen, wie t Mit diesem Problem umgehen?

+0

Vielleicht versuchen Sie nicht, Rekursion zu verwenden ... Setzen Sie es lieber in eine große While-Schleife. Sie können sogar einen Zähler setzen und nach einer bestimmten Anzahl von Wiederholungen zum Stoppen/Fehlschlagen bringen. – Paul

+0

Wenn Sie sicher sind, dass 'calcNum.isProbablePrime()' korrekt funktioniert, sollten Sie wie von Paul vorgeschlagen. – khachik

+0

Nun isProbablePrime() funktioniert gut, aber ich bekomme nie eine Primzahl von 2 Primzahlen .. Ich bekomme nur zusammengesetzte Primzahlen –

Antwort

1

Bitte meinen Kommentar unten Ihre Frage sehen ...

private void populateRandomPrimes() 
{ 
    while (true){ 
     onePrimeValue = RandomPrime.getValue(); 

     do 
     { 
      secondPrimeValue= RandomPrime.getValue(); 
     }while(onePrimeValue == secondPrimeValue); 

     BigInteger calcNum = new BigInteger(Integer.toString(onePrimeValue*secondPrimeValue)); 

     try 
     { 
      if (calcNum.isProbablePrime(20)){ 
       populateMultiplicativeForPlayer(); 
       return; 
      } 
     } 
     catch (Exception io) 
     { 
      io.printStackTrace(); 
     } 
    } 
} 
1

Bewegen Sie die calcNum Berechnung innerhalb der do-while-Schleife und eine zusätzliche Bedingung hinzu:

private void populateRandomPrimes() 
{ 
    onePrimeValue = RandomPrime.getValue(); 
    BigInteger calcNum = null; 
    do { 
     secondPrimeValue= RandomPrime.getValue(); 
     calcNum = new BigInteger(Integer.toString(onePrimeValue*secondPrimeValue)); 
    } while(onePrimeValue.equals(secondPrimeValue) && !(calcNum.isProbablePrime(20)); 

    //if you get here, calcNum isProbPrime, so no need to check again 
    try { 
     populateMultiplicativeForPlayer(); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

Sie sind in diesen laufen Problem, weil Sie keinen definitiven Basisfall für Ihre Rekursion haben. Verwenden Sie auch == nicht für Objekte, es sei denn, Sie wissen, was Sie tun. Ihre do-while Bedingung sollte .equals() verwendet hat, um zu vergleichen, onePrimeValue und secondPimeValue

Das Worst-Case-Szenario mit diesem Ansatz ist, dass Ihr Programm wird in einem infinite loop, weil die Ausgangsbedingung des steckt do-while-Schleife ist nie zufrieden. Um dies zu beheben, können Sie der Schleife eine dritte Bedingung hinzufügen, um sicherzustellen, dass sie nach einer festgelegten Anzahl von Iterationen beendet wird.

+0

gut 'secondPrimeValue' und' onePrimeValue' sind vom Typ 'int'. Also muss ich '.equals()' nicht verwenden. Und ich bin in der Tat nur in das schlechtere Szenario läuft :) –

+0

Das war nicht offensichtlich aus dem Code lesen, aber OK. –

1
private BigInteger generateAppropriateNumber() { 
    BigInteger result; 
    boolean isOk = false; 
    while (isOk == false) { 
     onePrimeValue = RandomPrime.getValue(); 
     do { 
      secondPrimeValue= RandomPrime.getValue(); 
     } while(onePrimeValue.equals(secondPrimeValue)); 
     BigInteger result = 
       new BigInteger(Integer.toString(onePrimeValue * secondPrimeValue)); 
     if (result.isProbablePrime(20)) { 
      isOk = true; 
     }    
    } 
    return result; 
} 

private void populateRandomPrimes() { 
    populateMultiplicativeForPlayer(generateAppropriateNumber()); 
} 

I.e.

  1. Verwenden Sie Schleife statt Rekursion, um Stapelerhöhung zu vermeiden.
  2. Verwenden Sie keine globalen Variablen. Es ist wirklich ein schlechter Stil.
Verwandte Themen