乘以大数的程序,执行直到循环不在cobol中工作

时间:2016-04-08 03:39:03

标签: cobol

当我执行x次计算时,代码工作正常。但是当我这样做的时候乘数不会改变。我是COBOL的新手,所以我不确定自己做错了什么。我基本上想要一个有效循环,直到乘数大于0为止。由于cobol没有递归,我用这种方式尝试,它在C中运行正常,但是它给了我问题就这里的循环而言。

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.

1 个答案:

答案 0 :(得分:1)

看起来你正在使用GnuCOBOL(或者更老的OpenCOBOL,GnuCOBOL是OpenCOBOL的新名称)。 2002 COBOL标准(现在由2014标准取代)引入了COBOL的递归(在PROGRAM-ID上是RECURSIVE),GnuCOBOL支持递归,在其他COBOL编译器中很常见。

除此之外,为什么在存在非曲折的替代方案时使用递归?

您有三个实际问题,已在问题的评论中涵盖了两个问题。

UNTIL。这意味着在这种情况存在之前,继续进行PERFORM"。它可以位于"顶部"迭代(第一件事)或底部(最后一件事)。一旦条件为真,PERFORM将不会执行。在条件最初为真时PERFORM是否执行取决于WITH TEST。 WITH TEST BEFORE(默认值)表示如果在遇到PERFORM时条件为真,则PERFORM将不会执行。 WITH TEST AFTER延迟测试,直到第一次执行代码块(对于内联PERFORM)或paragrap(s)/ SECTION完成。

遇到PERFORM时,

乘数已经大于零。您使用WITH TEST AFTER,因此您可以获得一次更改终止值。代码不会确保乘数不大于零,因此终止条件为真时,不会再次输入PERFORMed段落。

使用EQUAL TO ZERO,放弃WITH TEST AFTER。乘数不能为负数,也没有小数部分。当一个除以2并存储结果时,结果将为零。这肯定会在您的计划中每次都发生。这是你的终止条件。

您已定义答案,并将其用作添加的目标,但在添加之前没有保证值。在将其用作任何类型的计算目标之前,将其设置为零(VALUE子句,或MOVE ZERO TO ...或INITIALIZE ...)。但是,如果不需要初始值,请不要给它初始值。

如果第一次使用something是这样的:

ADD x TO something

然后你应该确保它有一个初始值。如果是这样的话:

MOVE x TO something

然后一个初始值只是一个混乱,不必要,从不需要,因为没有人会注意到它有初始值。

GnuCOBOL将/可以根据数据类型给出定义的存储初始值。这不一定可以移植到其他COBOL编译器,因此不应该依赖它。只有在需要时,明确的初始化也向未来的读者表明你知道自己在做什么。

您忘记结束自己的计划了。因为你忘了结束它,所以控制只是继续运行,最后一次到达你的calculation段,然后最终退出你的程序结束。 GnuCOBOL没有真正的问题,但是这种行为再次是不可移植的,并且你很幸运,当在程序的那个阶段执行时,被删除的代码没有任何变化。

除此之外,我建议在程序部门避免不必要的全停/句号。对输入进行错误检查。用更好的名字。你的乘数和被乘数最初是这样的,但在整个程序中调用它们是一件好事吗?

此处的程序只包含程序部门所需的全停/句点,初始化和终止条件已得到纠正。

   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 
       .