Primzahlen(Batch)

Aus IT074-Wiki

Wechseln zu: Navigation, Suche

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

Siehe auch