Похоже, что вы используете GnuCOBOL (или старую OpenCOBOL, GnuCOBOL это новое название для OpenCOBOL). Стандарт COBOL 2002 года (в настоящее время стандартом 2014 года) вводит рекурсию в COBOL (IS RECURSIVE по идентификатору PROGRAM-ID), а GnuCOBOL поддерживает рекурсию, и она довольно распространена среди других компиляторов COBOL.
Это в стороне, зачем использовать рекурсию для чего-то, когда есть не извилистая альтернатива?
У вас есть три актуальные проблемы, два из которых уже включены в комментарии к вашему вопросу.
UNTIL. Это означает, что «пока это условие не существует, продолжайте делать PERFORM». Он может быть расположен на «вершине» итерации (первое) или внизу (последнее). Когда условие истинно, PERFORM не будет выполняться. Независимо от того, выполняется ли PERFORM, когда условие изначально истинно, зависит от WITH TEST. С ИСПЫТАНИЕМ ДО (по умолчанию) означает, что PERFORM не будет выполняться вообще, если условие истинно, когда встречается PERFORM. WITH TEST AFTER задерживает тест до тех пор, пока не завершится первое выполнение кода (для встроенного PERFORM) или параграфа (ов)/SECTION.
множитель уже больше нуля, когда встречается PERFORM. Вы используете WITH TEST AFTER, поэтому вы получаете один снимок, чтобы изменить значение завершения. Код не делает ничего, чтобы убедиться, что множитель не больше нуля, поэтому абзац PERFORMed больше не будет введен, поскольку условие завершения является истинным.
Используйте EQUAL TO ZERO, выровняйте С ИСПЫТАНИЕМ ПОСЛЕ. множитель не может быть отрицательным, и он не имеет десятичной части. Когда один делится на два и результат сохраняется, этот результат будет равен нулю. Это обязательно и обязательно произойдет каждый раз в вашей программе. Это ваше условие завершения.
Вы определили ответ и используете его как цель добавления, но перед добавлением он не имеет гарантированного значения. Установите его в ноль (предложение 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
.
До множителя> 0? Разве вы не имеете в виду, когда множитель> 0? – Mike
да, извините, но. Должен ли я использовать пока? –
Либо это, либо «до множителя <= 0». Прошло 30 лет с тех пор, как я использовал COBOL на старом мэйнфрейме IBM. – Mike