Fehler Division durch null
Nachdem ich ein Programm in VBS und Pascal geschrieben hatte, wollte ich das ganze in einer Batch schreiben...
... und bekam prompt ein Problem. Mein Programm soll den größten gemeinsamen Teiler (ggt) und das kleinste gemeinsame Vielfache (kgv) nach dem euklidischen Algorithmus ausrechnen. In VBS sah das ganze schön aus und funktionierte auch schön. Es sah so aus:
So, und das hatte ich in eine Batch umschreiben wollen (es sind nur geringfügige Änderungen für Linux-Shellscripts erforderlich). Das sah dann so aus:
ABER: Direkt nach dem zweiten Schleifendurchlauf (die Schleife wird ja immer als Klotz durchgeführt) erhalte ich eine Fehlermeldung namens: Fehler: Division durch Null.
Un nü??
Danke für etwaige Antworten.
... und bekam prompt ein Problem. Mein Programm soll den größten gemeinsamen Teiler (ggt) und das kleinste gemeinsame Vielfache (kgv) nach dem euklidischen Algorithmus ausrechnen. In VBS sah das ganze schön aus und funktionierte auch schön. Es sah so aus:
option explicit
dim intAntw, intA, intB, intggt, intkgv
intAntw= MsgBox("Dieses Skript berechnet den ggT und das"&chr(13)&"kgV zweier von ihnen angegeben Zahlen."&chr(13)&"Fortfahren?",36,"ggT-kgV-Rechner")
if intAntw=7 then WScript.quit
intA= InputBox ("Bitte geben Sie die erste Zahl ein","ggT-kgV-Rechner","18")
intB= InputBox ("Bitte geben Sie die zweite Zahl ein","ggT-kgV-Rechner","60")
if intA=intB then
WScript.echo "Ich lache morgen drüber, OK? Man kann nicht von ein",chr(13)&"und derselben Zahl ggT und kgV berechnen!!"
WScript.quit
end if
intggt= fcnggt(intA,intB)
intkgV= intA*intB/intggt
WScript.echo "ggT("&intA&","&intB&")="&intggt
WScript.echo "kgv("&intA&","&intB&")="&intkgv
function fcnggt (intZ1, intZ2)
dim ArrIntFeld(1000), intI
arrintFeld(0)=intZ1
arrintFeld(1)=intZ2
for intI = 0 to 998
ArrIntFeld(intI+2)=ArrIntFeld(intI) mod ArrIntFeld(intI+1)
if ArrIntFeld(intI+2)=0 then
exit for
end if
if intI=998 then
WScript.echo "Sorry, aber die Zahlen sind eindeutig zu groß!!"
WScript.echo "Skriptverarbeitung wird abgebrochen"
wscript.quit
end if
next
fcnggt=ArrIntFeld(intI+1)
end function
@echo off
:: ggtkgv.bat made by Markus Wichmann 2005 & Copyright the same
:: Syntax: %0 zahl1 zahl2 [/s]
:: Berechnet das kleinste gemeinsame Vielfache und den größten gemeinsamen Teiler
call :paramcheck %1 %2
if %3==/s endlocal
call :ggt %1 %2
echo ggT(%1,%2)=%ggt%
set /a kgv=%1 * %2 / %ggt%
echo kgV(%1,%2)=%kgv%
goto :eof
:ggt
endlocal
set z1=%1
set z2=%2
for /l %%i in (1,1,1000) do (
set /a z3=!z1!%%!z2!
if z3==0 (
set ggt=!z2!
goto :eof
)
set z1=!z2!
set z2=!z3!
)
:paramcheck
if X%1==X (
echo Parameter 1 wurde nicht angegeben.
md 2>nul
goto :showhelp
)
if X%2==X (
echo Parameter 2 wurde nicht angegeben.
md 2>nul
goto :showhelp
)
if %1==/? goto :showhelp
if %1==-? goto :showhelp
if %1==/h goto :showhelp
if %1==-h goto :showhelp
set /a h=%1 - %2
if %h%==0 (
echo Einer der Parameter oder beide sind keine Zahlen oder gleichen sich
md 2>nul
goto :showhelp
)
goto :eof
:showhelp
echo Syntax:
echo ggtkgv zahl1 zahl2
echo zahl1,zahl2 Zahlen von denen der größte gemeinsame Teiler und das kleinste
echo gemeinsame Vielfache ermittelt werden soll.
exit /b 1
Un nü??
Danke für etwaige Antworten.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 19830
Url: https://administrator.de/contentid/19830
Ausgedruckt am: 25.11.2024 um 01:11 Uhr
4 Kommentare
Neuester Kommentar
Moin nullplan001,
war nichts Gravierendes - eher Tippfehler und eine Stelle, wo der CMD-Interpreter eben nicht alle Sprachelemente von VB-Skript abdeckt.
Die Tippfehler (weil da jeder reintappt früher oder später):
...
set z1=%1
set z2=%2
wenn dummerweise ein Leerzeichen dranhängt in dieser Eingabezeile, steht da "set z1=%1 "
Dann wird z1 beim übergebenen Parameter 28 statt der Zahl 28 zum String "28 "
workaround siehe unten im Batch.
~~~~~~~~~~~~~
~~~~~~~~~~~~~
set /a z3=!z1!%%!z2!
if z3==0 (
...so viel Mühe bei der MOD-Zeile... aber die Zeile darunter muss
if %z3%==0 ( ........lauten. Flüchtigkeitsfehler.
~~~~~~~~~~~~
~~~~~~~~~~~~
if %3==/s .................wenn kein dritter Parameter übergeben wird, steht da: "if ==/s " -->Syntaxfehler
...
..und ein Script-sprachliches Problem: der CMD-Interpreter kennt zwar FOR-Schleifen, aber kein "Exit For", wie Du es in VBS verwendet hast. Okay, die 1...1000-Schleife kostet kaum Zeit, aber er läuft sie halt bis 1000 durch, auch wenn er nach dem ersten Durchgang schon den ggT ermittelt hat.
ich habs mal ein bisschen geflickt.. der Output wäre z.B.:
Der marginal geänderte Code:
HTH Biber
war nichts Gravierendes - eher Tippfehler und eine Stelle, wo der CMD-Interpreter eben nicht alle Sprachelemente von VB-Skript abdeckt.
Die Tippfehler (weil da jeder reintappt früher oder später):
...
set z1=%1
set z2=%2
wenn dummerweise ein Leerzeichen dranhängt in dieser Eingabezeile, steht da "set z1=%1 "
Dann wird z1 beim übergebenen Parameter 28 statt der Zahl 28 zum String "28 "
workaround siehe unten im Batch.
~~~~~~~~~~~~~
~~~~~~~~~~~~~
set /a z3=!z1!%%!z2!
if z3==0 (
...so viel Mühe bei der MOD-Zeile... aber die Zeile darunter muss
if %z3%==0 ( ........lauten. Flüchtigkeitsfehler.
~~~~~~~~~~~~
~~~~~~~~~~~~
if %3==/s .................wenn kein dritter Parameter übergeben wird, steht da: "if ==/s " -->Syntaxfehler
...
..und ein Script-sprachliches Problem: der CMD-Interpreter kennt zwar FOR-Schleifen, aber kein "Exit For", wie Du es in VBS verwendet hast. Okay, die 1...1000-Schleife kostet kaum Zeit, aber er läuft sie halt bis 1000 durch, auch wenn er nach dem ersten Durchgang schon den ggT ermittelt hat.
ich habs mal ein bisschen geflickt.. der Output wäre z.B.:
>e:\kgVggT.bat 34 2654
ggT(34,2654)=2
kgV(34,2654)=45118
>e:\kgVggT.bat 27 3
ggT(27,3)=3
kgV(27,3)=27
>e:\kgVggT.bat 28 3
ggT(28,3)=1
kgV(28,3)=84
>e:\kgVggT.bat 12 15
ggT(12,15)=3
kgV(12,15)=60
::*** edited Biber *** @echo off
@echo off & setlocal enableDelayedExpansion
:: ggtkgv.bat made by Markus Wichmann 2005 & Copyright the same & No rights wanted By Beaver
:: Syntax: %0 zahl1 zahl2 [/s]
:: Berechnet das kleinste gemeinsame Vielfache und den größten gemeinsamen Teiler
set /a "ggT=0"
call :paramcheck %1 %2
::*** edited Biber *** if %3==/s endlocal
::*** Biber wenn jemals, dann so ***if [%3]==[/s] endlocal
call :ggt %1 %2
echo ggT(%1,%2)=%ggt%
set /a kgv=%1 * %2 / %ggt%
echo kgV(%1,%2)=%kgv%
goto :eof
:ggt
::*** deleted Biber *** endlocal
::*** edited Biber *** set z1=%1
::*** edited Biber *** set z2=%2
set /a "z1=%1"
set /a "z2=%2"
for /l %%i in (1,1,1000) do if !ggT! EQU 0 call :getggt
goto :eof
:getggt
set /a "z3=!z1!%%!z2!"
if %z3%==0 (
set /a "ggt=!z2!"
goto :eof
)
set /a "z1=!z2!"
set /a "z2=!z3!"
goto :eof
:paramcheck
if X%1==X (
echo Parameter 1 wurde nicht angegeben.
::*** delited Biber *** md 2>nul
goto :showhelp
)
if X%2==X (
echo Parameter 2 wurde nicht angegeben.
::*** edited Biber *** md 2>nul
goto :showhelp
)
if %1==/? goto :showhelp
if %1==-? goto :showhelp
if %1==/h goto :showhelp
if %1==-h goto :showhelp
Set /a "Nullcheck=%1*%2" >nul 2>nul
If Errorlevel 1 (
Echo Ein oder beide Parameter haben den Wert 0!
goto :Showhelp
)
set /a "h=%1 - %2"
if %h%==0 (
echo Einer der Parameter oder beide sind keine Zahlen oder gleichen sich
::*** edited Biber *** md 2>nul
goto :showhelp
)
goto :eof
:showhelp
echo Syntax:
echo ggtkgv zahl1 zahl2
echo zahl1,zahl2 Zahlen von denen der größte gemeinsame Teiler und das kleinste
echo gemeinsame Vielfache ermittelt werden soll.
exit /b 1
Moin nullplan001,
sorry, eines hatte ich gestern noch vergessen bzw. auch im Source nicht zu Ende geführt.
Da, wo Du bisher dieses "md 2>nul " stehen hattest...
Ziel des Ganzen ist je das Setzen eines Errorlevels. Da aber alle Errorlevels ohnehin in der :Showhelp gesetzt werden, kannst Du der natürlich auch eine "interne" Fehlerkennung setzen, die dann in der :Showhelp (und nur dort) in einen Exitcode umgesetzt wird.
...also im ganzen Satz:
HEUTE:
...steht an -zig Stellen "md 2>nul" == Setze Errorlevel auf 1
... wird in der :Showhelp ohnehin immer genau der gleiche Exitcode 1 gesetzt "exit /b 1"
HEUTEaber später am Tach)
...steht an -zig Stellen set "MyErrorLevel=2" oder ..3 oder 4... je nach Fehlerort
...und in der :Showhelp wird dann "Exit /b %MyErrorLevel%+0" gesetzt.
( "+0" nur für den Fall, dass an irgeneiner Stelle die Variable MyErrorlevel vergessen wurde/leer ist.)
Grüße
Biber
sorry, eines hatte ich gestern noch vergessen bzw. auch im Source nicht zu Ende geführt.
Da, wo Du bisher dieses "md 2>nul " stehen hattest...
Ziel des Ganzen ist je das Setzen eines Errorlevels. Da aber alle Errorlevels ohnehin in der :Showhelp gesetzt werden, kannst Du der natürlich auch eine "interne" Fehlerkennung setzen, die dann in der :Showhelp (und nur dort) in einen Exitcode umgesetzt wird.
...also im ganzen Satz:
HEUTE:
...steht an -zig Stellen "md 2>nul" == Setze Errorlevel auf 1
... wird in der :Showhelp ohnehin immer genau der gleiche Exitcode 1 gesetzt "exit /b 1"
HEUTEaber später am Tach)
...steht an -zig Stellen set "MyErrorLevel=2" oder ..3 oder 4... je nach Fehlerort
...und in der :Showhelp wird dann "Exit /b %MyErrorLevel%+0" gesetzt.
( "+0" nur für den Fall, dass an irgeneiner Stelle die Variable MyErrorlevel vergessen wurde/leer ist.)
Grüße
Biber
Moin, Markus,
sieh mal zu, dass Du den Editor wechselst - ich nehme zum Coden (selbst für Batch-Files) einen der Editoren á la TextPad oder UltraEdit - irgendetwas, dass AutoIndent-Mode hat und mir ein Syntax-Highlightning ermöglicht. Da kommen sicherlich Edit und M$'s NotePad nie hin.
Meinen NotePad habe ich zwar geringfügig getunt, weil er ja doch bei diesen oder jenen File-Typen laut Registry-Standard-Einstellungen automatisch aufklappt, aber einen "AutoIndent-Switch" in der Registry habe ich nicht gefunden. Auch nicht ernsthaft gesucht.
Die paar Keys, die Du ggf. nachtragen kannst in der Reg unter [HKCU\Software\Microsoft\Notepad] sind:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Notepad]
; ....die üblichen lass ich mal raus
"fWrap"=dword:00000001
; nix Zeilenbruch ohne zu fragen
"StatusBar"=dword:00000001
; Zeilen+Spaltenpos anzeigen
"fSaveWindowPositions"=dword:00000000
"fSavePageSettings"=dword:00000001
; Fensterpositionen merken nach Geschmack
;....
"lfFaceName"="Tahoma"
"lfPitchAndFamily"=dword:00000031
"iPointSize"=dword:00000064
; Tahoma als Schriftart in erträglicher Auflösung (ich nehme es ja nicht zum Coden)
;....
"szHeader"="&n &d &l"
"szTrailer"="Seite &s"
Glaube nicht, das sich aus Notepad mehr rausholen lässt. geh lieber auf http://www.textPad.de.
Grüße
Frank / der Biber aus Bremen
sieh mal zu, dass Du den Editor wechselst - ich nehme zum Coden (selbst für Batch-Files) einen der Editoren á la TextPad oder UltraEdit - irgendetwas, dass AutoIndent-Mode hat und mir ein Syntax-Highlightning ermöglicht. Da kommen sicherlich Edit und M$'s NotePad nie hin.
Meinen NotePad habe ich zwar geringfügig getunt, weil er ja doch bei diesen oder jenen File-Typen laut Registry-Standard-Einstellungen automatisch aufklappt, aber einen "AutoIndent-Switch" in der Registry habe ich nicht gefunden. Auch nicht ernsthaft gesucht.
Die paar Keys, die Du ggf. nachtragen kannst in der Reg unter [HKCU\Software\Microsoft\Notepad] sind:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Notepad]
; ....die üblichen lass ich mal raus
"fWrap"=dword:00000001
; nix Zeilenbruch ohne zu fragen
"StatusBar"=dword:00000001
; Zeilen+Spaltenpos anzeigen
"fSaveWindowPositions"=dword:00000000
"fSavePageSettings"=dword:00000001
; Fensterpositionen merken nach Geschmack
;....
"lfFaceName"="Tahoma"
"lfPitchAndFamily"=dword:00000031
"iPointSize"=dword:00000064
; Tahoma als Schriftart in erträglicher Auflösung (ich nehme es ja nicht zum Coden)
;....
"szHeader"="&n &d &l"
"szTrailer"="Seite &s"
Glaube nicht, das sich aus Notepad mehr rausholen lässt. geh lieber auf http://www.textPad.de.
Grüße
Frank / der Biber aus Bremen