Primzalenberechnung große zahlen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Primzalenberechnung große zahlen

    Hallo,

    Bei der berechnung von Primzhalen bekomme ich einen Stackoverflow wenn die zahlen zu groß sind (ca. ab 600.000), was kann ich dagegen tun, damit die berechnung für wesentlich größere Zahlen durchgeführt werden kann?

    Quellcode

    1. #include <cmath>
    2. #include <iostream>
    3. #define GROESSE 600000
    4. int eingabe(){
    5. int n;
    6. std::cout << "Feldgröße N: ";
    7. std::cin >> n;
    8. return n;
    9. }
    10. void berechnung(int *feld){
    11. int i;
    12. int j;
    13. //Feldinhalt mit 0 initialisieren
    14. for(i = 0; i <= GROESSE; i++){
    15. feld[i]=1;
    16. }
    17. //i auf erste Primzahl(2) setzen
    18. i=2;
    19. while(i <= GROESSE/2){
    20. while(feld[i]!=1 && i<=GROESSE){
    21. i++;
    22. }
    23. //Vielfaches von i streichen(0)
    24. for(j = 2*i; j <= GROESSE; j += i){
    25. feld[j] = 0;
    26. }
    27. //Suchen nach erst gestrichener Zahl(0)
    28. i++;
    29. }
    30. }
    31. void ausgabe(int *feld){
    32. int i;
    33. for(i = 2; i <= GROESSE; i++){
    34. if(feld[i] == 1){
    35. std::cout << "Primzahl: " << i << "\n";
    36. }
    37. }
    38. }
    39. int main(void){
    40. int n = eingabe();
    41. int feld[GROESSE];
    42. if(feld!=NULL){
    43. berechnung(feld);
    44. ausgabe(feld);
    45. }else{
    46. std::cout << "Es Konnte kein Speicher reserviert werden!!!";
    47. }
    48. std::cout << "Feldgröße N: ";
    49. std::cin >> n;
    50. return 0;
    51. }
    Alles anzeigen


    viele grüße & thx
    bo
  • LOL - ich hab auch sowas gemacht ... Du hast natürlich nen etwas ungünstiges
    Array gewählt, ich geh mal davon aus, Du nimmst diese WegstreichMethode.
    Dann nutze BOOL statt INT ... damit kannste 8-mal soviel speichern
    und theoretisch lässt sich der Code noch optimieren, wenn Du alle
    geraden Zahlen weglässt ;) ... aber das wird dann schonwieder
    schwierig. Hier mein unsauberer Beitrag zum Thema:

    Quellcode

    1. #include <cstdlib>
    2. #include <iostream>
    3. #include <math.h>
    4. using namespace std;
    5. int main(int argc, char *argv[])
    6. {
    7. long int anzahl = 0;
    8. bool const TRUE = 1;
    9. bool const FALSE = 0;
    10. char Frage;
    11. do
    12. {
    13. anzahl = 0;
    14. do
    15. {
    16. cout << "Wieviele Primzahlen sollen es denn sein?: ";
    17. cin >> anzahl;
    18. cout << "\nDann rechne ich ma ...\n";
    19. }
    20. while (anzahl <= 0);
    21. bool *array = new bool[anzahl+1];
    22. bool *gitter = array;
    23. // naja erstmal davon ausgehen, alles sind primzahlen ;-)
    24. for (long int primzahl = 0; primzahl <= anzahl+1; primzahl++)
    25. *(gitter+primzahl)=TRUE;
    26. // dann alle vielfachen der zahlen streichen, wobei ich nur bis zu
    27. // 1/3 ALLER zahlen durchmuss, da ja vielfache von 3 sonst ne ;-)
    28. //ja ziemlich geil geschachtelt, gilt alles als 1 Zeile 8-)
    29. for(long int primzahl = 2; primzahl <= (long double) anzahl/3; primzahl++ )
    30. if ( *(gitter+primzahl) == TRUE )
    31. for(long int getestet = primzahl*2 ; getestet <= anzahl+1; getestet+=primzahl)
    32. if ( getestet <= anzahl+1)
    33. *(gitter+getestet) = FALSE;
    34. // da question
    35. Frage = 0;
    36. do{
    37. cout << "\nmöchten sie das Ergebnis Dezimal, Hexadezimal, Oktal oder Binaer? [D/H/O/B]: ";
    38. cin >> Frage;
    39. }
    40. while (Frage != 'D' & Frage != 'd' & Frage != 'H' & Frage != 'h'
    41. & Frage != 'O' & Frage != 'o' & Frage != 'B' & Frage != 'b');
    42. // und da Ausgabe
    43. cout << "Die Primzahlen lauten: \n";
    44. for(long int primzahl = 0; primzahl <= anzahl ;primzahl++)
    45. if ( *(gitter+primzahl) == TRUE)
    46. switch(Frage)
    47. {
    48. case 'd' : case 'D' :
    49. {
    50. cout << dec << primzahl << "\t";
    51. break;
    52. }
    53. case 'h' : case 'H' :
    54. {
    55. cout << hex << primzahl << "\t";
    56. break;
    57. }
    58. case 'o' : case 'O' :
    59. {
    60. cout << oct << primzahl << "\t";
    61. break;
    62. }
    63. case 'b' : case 'B' :
    64. {
    65. int maxpot = (int) (log((long double) anzahl)/log((long double) 2) + 1 );
    66. long int newprime = primzahl;
    67. for (int j = maxpot; j >= 0; j--)
    68. {
    69. if (newprime - pow(2,j) >= 0)
    70. {
    71. newprime-=(long int) pow(2,j);
    72. cout << "1";
    73. }
    74. else
    75. {
    76. cout << "0";
    77. }
    78. if ( ( (double)( (int) (j/2)) == ((double)j/2)) && j != 0)
    79. cout << ".";
    80. }
    81. cout << "\n";
    82. break;
    83. }
    84. default:
    85. {
    86. cout << "DAS DÜRFTE GARNICHT PASSIEREN - PROGRAMMIERFEHLER !!! " << Frage;
    87. break;
    88. }
    89. }
    90. delete[] array;
    91. // nochma ? nich ? schade.
    92. Frage = 0;
    93. do{
    94. cout << "\n\nnochmal ? [J/N]: ";
    95. cin >> Frage;
    96. }
    97. while (Frage != 'J' & Frage != 'j' & Frage != 'N' & Frage != 'n');
    98. }
    99. while(Frage == 'J' || Frage == 'j') ;
    100. // system("PAUSE");
    101. return EXIT_SUCCESS;
    102. }
    Alles anzeigen


    Kompiliert ohne Fehler bei mia und läuft gut, kann auch mal ne Millionen
    eingeben, ohne dasser abkackt. Problematisch ist nur die Ausgabe, weil
    ich JEDESMAL erst nen Switch/CASE mache, aber ansonsten hätte ich
    die Schleife 4 mal programmieren müssen - naja - Geschmacksfrage.
    Das Array hat an der Stell (Zahl) nur den wert Wahr oder Falsch.
    *wobei ich glaube, dass ich True un False zahlentechnisch verwechselt
    habe, aber macht ja nix - man kanns ja einfach tauschen ?*
    ... ich progge auch noch net so lang 8-P ...
  • Oh hab bei mir noch nen lolligen trivialen Fehler gefunden.
    Da ich die Zahlen nur bis Maximal/3 durchnehme, weil ich
    ja schon weiss, dass 3 ne Primzahl is, ergibts sich bei der
    Eingabe, dass man nur 5 Primzahlen will der Fehler, dasser
    garnich bis zur 3 kommt mitm wegstreichen und daher dann
    komischerweise vergisst die 4 wegzustreichen. Bei 7 gehts
    wieder. Naja - mit so minimalen Werte rechner ja keiner,
    aber zur Not streicht man 4 per Hand weg ;) so vonweg
    if ( max<=5 ) setze *(array+4)=False;
    ... voll die Flicklösung, aber eigentlich interessierts ja keinen.