Primzahlen(Batch)
Aus IT074-Wiki
Zum Errechnen der Primzahlen wird die verzögerte Variablenauflösung verwendet. Ich habe es noch nicht hinbekommen CMD-Aufruf und Ausführen der Primzahlenberechnung in der neuen CMD in einer einzigen Batch-Datei unterzukriegen. Entweder man startet selbst eine CMD mit dem Paramter "/V:on" oder man erstellt sich eine zweite Batch-Datei, welche eine neue CMD mit dem Parameter startet und initial das Primzahlen-Batch darin ausführt. (cmd /V:on primzahlen.bat)
Das folgende Script ist mit einem Eingabemenü versehen und versucht weitestgehend Fehleingaben abzufangen, ist aber noch nicht perfektioniert, da Funktionszeichen (&, >, <, |) noch ein Problem darstellen. Bin noch am schauen, wie diese als Plaintext gelesen werden.
Bei größeren Zahlen ab 5 Stellen wird die Berechnung relativ zäh. Ich empfehle nicht die maximal mögliche Zahl zu verwenden, da dies eventuell Tage dauern könnte.
Es gibt jetzt zwei Varianten.
Die erste vergibt alle ungeraden Werte einer Variable (Ausnahme 1 und 2) und setzt anschließend jedes Vielfache, was nicht gerade ist, ab 3 aufwärts = 0. D.h. num9, num15, num21 usw. werden 0. Dann findet er die 5 und setzt num25, num35, usw. 0.
Variante 2 geht den Weg über den Rest 1 oder 5, den eine Primzahl >=5 bei Teilung durch 6 hat und initialisiert erst wenn dies gegeben ist die Variable mit der Primzahl.
Variante 2 hat sich bei den Schnelligkeitstests als ca. 30% schneller als Variante 1 herausgestellt.
Variante 1
@echo off REM ### Variante 1 -> 1 und 2 werden hart gesetzt + 3+2n REM ### Es werden für 3+2n alle Vielfachen 0 gesetzt, die ungerade sind. cls echo Bitte in einer CMD mit Parameter /V:on ausuehren (cmd /V:on). echo Dies aktiviert die verzoegerte Variablenaufloesung und ist erforderlich. echo. pause :input_max_number cls echo Bis zu inklusive welcher Zahl sollen alle Primzahlen ausgegeben werden? echo. echo max. 2.147.483.647 (ohne Tausenderpunkte), da Batch echo eine feste Groesse von 32 Bit fuer Zahlen verwendet. echo =^> 31 Bit + Vorzeichenbit = Werteberech von +2147483647 bis -2147483648 echo. echo keine Eingabe = Ende echo. set max_num=x set /p max_num=Eingabe: if %max_num% GEQ 1 ( if %max_num% LEQ 2147483647 goto file_or_console ) if x%max_num%==xx goto end goto error_max_number :file_or_console cls echo Wie soll die Ausgabe erfolgen? echo 1 = Datei echo 2 = Konsole set output=x set /p output=Eingabe: if %output%==1 goto calculate_prime_numbers if %output%==2 goto calculate_prime_numbers goto error_file_or_console :calculate_prime_numbers set time_start=%time% echo. echo Berechne alle Primzahlen bis %max_num%... echo. set num1=1 if %max_num% EQU 1 goto print set num2=2 if %max_num% EQU 2 goto print for /L %%a in (3,2,%max_num%) do ( set num%%a=%%a ) set /A max_num_half=%max_num%/2 for /L %%a in (3,2,%max_num_half%) do ( if !num%%a! GEQ 3 ( set /A start=%%a*2 for /L %%b in (!start!,%%a,%max_num%) do ( set /A mod=%%b%%2 if !mod! NEQ 0 ( if !num%%b! NEQ 0 ( set num%%b=0 ) ) ) ) ) :howto_print if %output%==1 goto print_file if %output%==2 goto print_console :print_file if exist %CD%\primzahlen_bis_%max_num%.txt del %CD%\primzahlen_bis_%max_num%.txt echo %num1% > primzahlen_bis_%max_num%.txt if %max_num% EQU 1 goto finish echo %num2% >> primzahlen_bis_%max_num%.txt if %max_num% EQU 2 goto finish for /L %%a in (3,2,%max_num%) do ( if !num%%a! GEQ 3 ( echo !num%%a! >> primzahlen_bis_%max_num%.txt ) ) echo Datei %CD%\primzahlen_bis_%max_num%.txt erstellt. goto finish :print_console echo %num1% if %max_num% EQU 1 goto finish echo %num2% if %max_num% EQU 2 goto finish for /L %%a in (3,2,%max_num%) do ( if !num%%a! GEQ 3 ( echo !num%%a! ) ) :finish echo. set time_end=%time% echo Start, Ende und Dauer: echo ---------------------- echo S: %time_start% echo E: %time_end% set start_hour=%time_start:~0,2% set start_min=%time_start:~3,2% set start_sec=%time_start:~6,2% set start_hdrt_sec=%time_start:~-2% set start_blank=%start_hour%%start_min%%start_sec%%start_hdrt_sec% set end_hour=%time_end:~0,2% set end_min=%time_end:~3,2% set end_sec=%time_end:~6,2% set end_hdrt_sec=%time_end:~-2% set end_blank=%end_hour%%end_min%%end_sec%%end_hdrt_sec% set /A duration=%end_blank%-%start_blank% echo D: %duration:~0,-6%:%duration:~0,-4%:%duration:~0,-2%,%duration:~-2% echo. pause goto end :error_max_number echo. echo Der eingegebene Wert "%max_num%" liegt nicht zwischen 1 und 2147483647. echo Versuchs nochmal. echo. pause goto input_max_number :error_file_or_console echo. echo Der eingegebene Wert "%output%" ist nicht erlaubt. echo Versuchs nochmal. echo. pause goto file_or_console :end
Variante 2
@echo off REM ### Variante 2 -> 1 und 2 werden hart gesetzt + 3+2n REM ### Es werden alle 3+2n auf Ihren Rest bei Teilung durch 6 geprüft. REM ### Ist Rest nicht 1 oder 5 setze Wert = 0 cls echo Bitte in einer CMD mit Parameter /V:on ausuehren (cmd /V:on). echo Dies aktiviert die verzoegerte Variablenaufloesung und ist erforderlich. echo. pause :input_max_number cls echo Bis zu inklusive welcher Zahl sollen alle Primzahlen ausgegeben werden? echo. echo max. 2.147.483.647 (ohne Tausenderpunkte), da Batch echo eine feste Groesse von 32 Bit fuer Zahlen verwendet. echo =^> 31 Bit + Vorzeichenbit = Werteberech von +2147483647 bis -2147483648 echo. echo keine Eingabe = Ende echo. set max_num=x set /p max_num=Eingabe: if %max_num% GEQ 1 ( if %max_num% LEQ 2147483647 goto file_or_console ) if x%max_num%==xx goto end goto error_max_number :file_or_console cls echo Wie soll die Ausgabe erfolgen? echo 1 = Datei echo 2 = Konsole set output=x set /p output=Eingabe: if %output%==1 goto calculate_prime_numbers if %output%==2 goto calculate_prime_numbers goto error_file_or_console :calculate_prime_numbers set time_start=%time% echo. echo Berechne alle Primzahlen bis %max_num%... echo. set num1=1 if %max_num% EQU 1 goto howto_print set num2=2 if %max_num% EQU 2 goto howto_print set num3=3 if %max_num% EQU 3 goto howto_print for /L %%a in (5,2,%max_num%) do ( set /A num_mod=%%a%%6 if !num_mod! EQU 1 ( if !num_mod! EQU 5 ( set num%%a=%%a ) ) ) :howto_print if %output%==1 goto print_file if %output%==2 goto print_console :print_file if exist %CD%\primzahlen_bis_%max_num%.txt del %CD%\primzahlen_bis_%max_num%.txt echo %num1% > primzahlen_bis_%max_num%.txt if %max_num% EQU 1 goto finish echo %num2% >> primzahlen_bis_%max_num%.txt if %max_num% EQU 2 goto finish for /L %%a in (3,2,%max_num%) do ( if !num%%a! GEQ 3 ( echo !num%%a! >> primzahlen_bis_%max_num%.txt ) ) echo Datei %CD%\primzahlen_bis_%max_num%.txt erstellt. goto finish :print_console echo %num1% if %max_num% EQU 1 goto finish echo %num2% if %max_num% EQU 2 goto finish for /L %%a in (3,2,%max_num%) do ( if !num%%a! GEQ 3 ( echo !num%%a! ) ) :finish echo. set time_end=%time% echo Start, Ende und Dauer: echo ---------------------- echo S: %time_start% echo E: %time_end% set start_hour=%time_start:~0,2% set start_min=%time_start:~3,2% set start_sec=%time_start:~6,2% set start_hdrt_sec=%time_start:~-2% set start_blank=%start_hour%%start_min%%start_sec%%start_hdrt_sec% set end_hour=%time_end:~0,2% set end_min=%time_end:~3,2% set end_sec=%time_end:~6,2% set end_hdrt_sec=%time_end:~-2% set end_blank=%end_hour%%end_min%%end_sec%%end_hdrt_sec% set /A duration=%end_blank%-%start_blank% echo D: %duration:~0,-6%:%duration:~0,-4%:%duration:~0,-2%,%duration:~-2% echo. pause goto end :error_max_number echo. echo Der eingegebene Wert "%max_num%" liegt nicht zwischen 1 und 2147483647. echo Versuchs nochmal. echo. pause goto input_max_number :error_file_or_console echo. echo Der eingegebene Wert "%output%" ist nicht erlaubt. echo Versuchs nochmal. echo. pause goto file_or_console :end

