2016-04-08 7 views
0

Der Code funktioniert gut, wenn ich die Berechnung x mal durchführen. aber der Multiplikator ändert sich nicht, wenn ich es so mache. Ich bin neu bei COBOL, also bin ich mir nicht sicher, was ich falsch mache. Ich möchte im Grunde eine while-Schleife, die funktioniert, bis Multiplikator größer als 0 ist. Da cobol keine Rekursion hat, versuche ich es so, es funktioniert gut in C, aber es gibt mir Probleme in Bezug auf die Schleife hier.Programm der Multiplikation großer Zahlen, führen, bis die Schleife in Cobol nicht funktioniert

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). 

procedure division. 
begin. 
    display 'multiplier?'. 
    accept multiplier. 
    display 'multiplicand?'. 
    accept multiplicand. 
    perform calculation 
     with test after 
     until multiplier > 0. 
    display answer. 

calculation. 
    if ((function mod(multiplier, 2)) = 1) then 
     add multiplicand to answer 
    end-if. 
    divide 2 into multiplier. 
    multiply 2 by multiplicand. 
+0

Bis Multiplikator> 0? Meinst du nicht, während Multiplikator> 0? – Mike

+0

ja, tut mir leid, während. sollte ich während verwenden? –

+2

Entweder das oder "bis Multiplikator <= 0". Es ist 30 Jahre her, dass ich COBOL auf dem alten IBM Mainframe verwendet habe. – Mike

Antwort

1

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 
     . 
+0

Frage ohne Hinweis: Gibt es eine maximale Länge für ein 9s-Feld in GNUCobol oder ist die alte 9 (18) noch durchgesetzt (mit Auswirkungen von Compiler-Abhängigkeit für die aktuelle Frage.) – Magoo

+0

@Magoo GnuCOBOL kann 36 Ziffern machen. IBM kann 31 durch Compiler-Option, durch Sprachenerweiterung auf den 85 Standard. Der aktuelle Standard ist 31. Für Portabilität wäre 18 vielleicht zuverlässiger, obwohl ich denke, dass viele, wenn nicht alle Compiler 31 erlauben würden. Ich bin mir nicht sicher, ob maximal 18 nicht genug wären :-) –

Verwandte Themen