COBOL - отличный ответ от мэйнфрейма к ПК для одного и того же COMPUTE

У меня есть эта очень простая фиктивная программа COBOL, которая делает фиктивный COMPUTE и отображает результат.

   ID DIVISION.
   PROGRAM-ID. DUMMYPGM.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 NUM-A PIC 9(3) VALUE 399.
   01 NUM-B PIC 9(3) VALUE 211.
   01 NUM-C PIC 9(3).
  *
   PROCEDURE DIVISION.
   MAIN.
       COMPUTE NUM-C = ((NUM-A / 100) - (NUM-B / 100)) * 100
       DISPLAY 'NUM-C IS ' NUM-C
       STOP RUN.

Когда я компилирую этот код на мейнфрейме (с компилятором MVS Enterprise COBOL V4.2) и выполняю его, я получаю "NUM-C IS 100", вероятно, потому что (399/100) рассматривается как 3 вместо 3.99 в расчете (а также для 211/100).

Но когда я компилирую тот же точный код на ПК (с компилятором GnuCobol) и выполняю его, я получаю "NUM-C IS 188". Ответ ПК правильный, но я бы хотел, чтобы он вел себя как мэйнфрейм (и, таким образом, терял точность в этом вычисляемом выражении, чтобы дать 100 вместо 188)... Как мне это сделать?

Причиной этого является общее выражение этого кода:

 COMPUTE PDISCR = (((((X(1) + DX - XBRAK) * (ABRAK(1) / 1000)) / 100)
                  + PHT(1) + DPH - PHBRAK) * 2) + ((V(1) + DV 
                  + VBRAKMPM) * (V(1) + DV - VBRAKMPM) / 100000)) 

Это часть 50-летней программы моделирования поездов, которую мне нужно перенести на GnuCOBOL. Все поля, используемые в COMPUTE, являются целыми числами. Мне нужно получить тот же ответ от GnuCOBOL.

Подтверждено для OpenCOBOL/GnuCOBOL до 2.0.

Ответ 1

Поскольку похоже, что IBM обрезает ваши значения, а GnuCobol этого не делает, вы можете использовать функции GnuCobol для эмуляции того, как IBM это делает.

Для положительных целых чисел, по крайней мере, это возможно так же просто, как:

COMPUTE NUM-C = ((INTEGER(NUM-A / 100)) - (INTEGER(NUM-B / 100))) * 100

Я не тестировал, работает ли это для отрицательных целых чисел, поскольку (1) doco, кажется, указывает на то, что оно округляется к отрицательной бесконечности, а не к нулю; (2) не существует функции TRUNCATE; и (3) Я предположил, что вам все равно, так как вы все же не подписали типы данных.

Если вам нужно обрабатывать негативы, есть математические методы, которые сделают это для вас, я бы предложил задать вопрос по другому вопросу.

Ответ 2

https://lwn.net/Articles/733129/

В этой ссылке упоминается новая опция std для gnuCobol 2.2: ibm-strict. Интересно, заставит ли это выражение compute делать то, что вы хотите.