2016-10-04 9 views
10

У меня есть эта очень простая манекена программа 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.

+0

Извините за непонимание: сложным я имел в виду несколько операций в одном вычислении (здесь есть две деления и одно умножение вместо одной операции). Я понимаю, что код не очень хорош, но это всего лишь доказательство концепции. Я вообще хотел озвучить превосходство или что-то еще, поэтому я отредактировал свой пост. –

+0

Что касается выпуска GnuCOBOL, я написал cobc -V и получил следующее: cobc (OpenCOBOL) 1.1.0 Copyright (C) 2001-2009 Keisuke Nishida/Roger Пока Построен 10 сентября 2010 10:12:33 Упакован 06 февраля 2009 10:30:55 CET –

+0

Я знаю, что возможным решением было бы изолировать каждый шаг вычисления в разных целочисленных переменных, но я хочу найти лучшее решение, потому что здесь приведен пример инструкции COMPUTE из кода, который я работающий по: COMPUTE PDISCR = ((((X (1) + DX - XBRAK) * (ABRAK (1)/1000)) /100) + PHT (1) + DPH - PHBRAK) * 2) + ((V (1) + DV + VBRAKMPM) * (V (1) + DV - VBRAKMPM)/100000)) –

ответ

0

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

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

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

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

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