Es sieht aus wie Sie verwenden Gnucobol (oder eine ältere OpenCOBOL ist Gnucobol der neue Name für OpenCOBOL). Der COBOL-Standard 2002 (der jetzt durch den Standard 2014 ersetzt wurde) führte eine Rekursion zu COBOL ein (IS RECURSIVE auf der PROGRAM-ID), und GnuCOBOL unterstützt Rekursion, und das ist unter anderen COBOL-Compilern ziemlich üblich.
Abgesehen davon, warum Rekursion für etwas verwenden, wenn es eine nicht-quälende Alternative gibt?
Sie haben drei tatsächliche Probleme, zwei in den Kommentaren zu Ihrer Frage bereits abgedeckt.
UNTIL. Dies bedeutet, "bis diese Bedingung erfüllt ist, mach weiter PERFORM". Es kann an der "Spitze" der Iteration (die erste Sache) oder an der Unterseite (die letzte Sache) lokalisiert werden. Sobald die Bedingung erfüllt ist, wird PERFORM nicht ausgeführt. Ob PERFORM jemals ausgeführt wird, wenn die Bedingung anfänglich wahr ist, hängt von WITH TEST ab. WITH TEST BEFORE (der Standardwert) bedeutet, dass PERFORM überhaupt nicht ausgeführt wird, wenn die Bedingung wahr ist, wenn PERFORM auftritt. WITH TEST AFTER verzögert den Test, bis die erste Ausführung des Codeblocks (für eine Inline-PERFORM) oder Paraprag (s)/SECTION abgeschlossen ist.
Multiplikator ist bereits größer als Null, wenn die PERFORM auftritt. Sie verwenden WITH TEST AFTER, so erhalten Sie eine Aufnahme, um den Terminierungswert zu ändern. Der Code stellt nicht sicher, dass der Multiplikator nicht größer als Null ist. Daher wird der PERFORMed-Absatz nicht erneut eingegeben, da die Beendigungsbedingung wahr ist.
Verwenden Sie EQUAL TO NULL, trennen Sie den WITH TEST AFTER. Multiplikator kann nicht negativ sein, und er hat keinen Dezimalteil. Wenn eins durch zwei geteilt wird und das Ergebnis gespeichert wird, ist das Ergebnis Null. Dies wird sicher und sicher jedes einzelne Mal in Ihrem Programm passieren. Es ist deine Beendigungsbedingung.
Sie haben die Antwort definiert und verwenden sie als Ziel einer Addition, aber vor der Addition hat sie keinen garantierten Wert. Setzen Sie ihn auf Null (VALUE-Klausel oder MOVE NULL TO ... oder INITIALIZE ...), bevor Sie ihn als Ziel einer Berechnung eines beliebigen Typs verwenden. Geben Sie ihm jedoch keinen Anfangswert, wenn er keinen benötigt.
Wenn das erste Mal something
verwendet wird, ist wie folgt:
ADD x TO something
Dann stellen Sie sicher, sollte es einen Anfangswert hat. Wenn es so ist:
MOVE x TO something
Dann ein Anfangswert ist nur eine Verwirrung, unnötig, nie gebraucht, denn nichts wird jemals bemerkt, dass Anfangswert hat.
GnuCOBOL gibt/kann definierte Speicheranfangswerte je nach Datentyp angeben. Dies ist nicht unbedingt übertragbar auf andere COBOL-Compiler, daher sollte man sich nicht darauf verlassen. Die explizite Initialisierung, nur wenn nötig, zeigt auch zukünftigen Lesern, dass Sie wissen, was Sie tun.
Sie haben vergessen, Ihr Programm zu beenden.Weil Sie vergessen haben, es zu beenden, läuft die Kontrolle einfach weiter und kommt ein letztes Mal in Ihren calculation
Absatz, bevor Sie schließlich das Ende Ihres Programms fallen lassen. GnuCOBOL hat damit kein wirkliches Problem, aber dieses Verhalten ist auch nicht portabel, und Sie haben nur Glück, dass der Code, in den hineingegangen wird, nichts ändert, wenn er in dieser Phase des Programms ausgeführt wird.
Ansonsten würde ich empfehlen unnötige Pausen in der PROCEDURE DIVISION zu vermeiden. Fehler bei der Eingabe haben. Verwenden Sie bessere Namen. Ihr Multiplikator und Multiplikand sind das anfangs, aber ist das eine gute und klare Sache, sie während des gesamten Programms zu nennen?
Hier ist Ihr Programm mit nur den erforderlichen Vollpausen/Perioden in der PROCEDURE DIVISION, Initialisierungs- und Abbruchbedingung korrigiert.
identification division.
program-id. multiplication.
data division.
working-storage section.
01 multiplier picture 9(36).
01 multiplicand picture 9(36).
01 answer picture 9(36) VALUE ZERO.
procedure division.
display 'multiplier?'
accept multiplier
display 'multiplicand?'
accept multiplicand
perform calculation
until multiplier = 0
display answer
goback (or stop run or exit program)
.
calculation.
if ((function mod(multiplier, 2)) = 1) then
add multiplicand to answer
end-if
divide 2 into multiplier
multiply 2 by multiplicand
.
Bis Multiplikator> 0? Meinst du nicht, während Multiplikator> 0? – Mike
ja, tut mir leid, während. sollte ich während verwenden? –
Entweder das oder "bis Multiplikator <= 0". Es ist 30 Jahre her, dass ich COBOL auf dem alten IBM Mainframe verwendet habe. – Mike