Проблема с переносом COBOL в переменную comp-3 - PullRequest
8 голосов
/ 02 июля 2010

У меня возникла следующая проблема в программе на COBOL, работающей в OpenVMS.

У меня есть следующее объявление переменной:

       01 STRUCT-1.
           02 FIELD-A       PIC S9(6) COMP-3.
           02 FIELD-B       PIC S9(8) COMP-3.

       01 STRUCT-2.
           03 SUB-STRUCT-1.
               05 FIELD-A   PIC 9(2).
               05 FIELD-B   PIC 9(4).
           03 SUB-STRUCT-2.
               05 FIELD-A   PIC 9(4).
               05 FIELD-B   PIC 9(2).
               05 FIELD-C   PIC 9(2).

И следующий код:

      * 1st Test:     
           MOVE 112011   TO FIELD-A OF STRUCT-1
           MOVE 20100113 TO FIELD-B OF STRUCT-1

           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 CONVERSION
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 CONVERSION

      * 2nd Test:
           MOVE 112011   TO SUB-STRUCT-1.
           MOVE 20100113 TO SUB-STRUCT-2.
           MOVE SUB-STRUCT-1 TO FIELD-A OF STRUCT-1
           MOVE SUB-STRUCT-2 TO FIELD-B OF STRUCT-1

           DISPLAY "SUB-STRUCT-1  : " SUB-STRUCT-1
           DISPLAY "SUB-STRUCT-2  : " SUB-STRUCT-2
           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 CONVERSION
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 CONVERSION

Какие выходы:

FIELD-A       :  112011
FIELD-B       :  20100113
SUB-STRUCT-1  : 112011
SUB-STRUCT-2  : 20100113
FIELD-A       :  131323
FIELD-B       :  23031303

Почему FIELD-A и FIELD-B содержат значения, отличные от того, что я ввел в них во втором тесте?

У меня есть другие перемещения от DISPLAY до COMP-3 переменных в моей программе, где я не получаю такое поведение.

Ответы [ 2 ]

4 голосов
/ 02 июля 2010

В COBOL данные на уровне группы не содержат типов и перемещаются без приведения.

Данные уровня элемента всегда имеют связанный тип данных. набранный данные приводятся в соответствии с типом принимающего элемента в течение MOVE.

В первом случае вы MOVE переводите буквенное числовое значение (112011) в упакованное десятичное поле, и компилятор преобразует его в правильный тип данных в процессе. Как и следовало ожидать на любом языке программирования.

Во втором случае вы MOVE литеральное значение для элемента группы. Поскольку это элемент группы, компилятор не может «знать» предполагаемый тип данных, поэтому он всегда выполняет групповые перемещения как символьные данные (без числовых преобразований). Это нормально, когда у принимающего предмета есть предложение PICTURE, которое совместимо с символьными данными - которые FIELD-A и FIELD-B SUB-STRUCT-1 являются Нет никакой разницы во внутреннем представлении 9 при сохранении как PIC X и при сохранении как PIC 9. Предполагается, что оба USAGE DISPLAY.

Теперь, когда вы переходите на групповой уровень с SUB-STRUCT-1 на COMP-3 (Packed Decimal), вы фактически указываете компилятору не преобразовывать формат DISPLAY в COMP-3. И это то, что вы получаете.

Попробуйте следующие модификации вашего кода. Использование REDEFINES создает числовой элементарный элемент для перемещения. КОБОЛ сделает соответствующее преобразование данных при перемещении элементарных данных.


       01 STRUCT-2.                  
           03 SUB-STRUCT-1.          
               05 FIELD-A   PIC 9(2).
               05 FIELD-B   PIC 9(4).
           03 SUB-STRUCT-1N REDEFINES
              SUB-STRUCT-1  PIC 9(6).
           03 SUB-STRUCT-2.          
               05 FIELD-A   PIC 9(4).
               05 FIELD-B   PIC 9(2).
               05 FIELD-C   PIC 9(2).
           03 SUB-STRUCT-2N REDEFINES
               SUB-STRUCT-2 PIC 9(8).

и следующий код:


      * 3RD TEST:                                         
           MOVE 112011   TO SUB-STRUCT-1.                 
           MOVE 20100113 TO SUB-STRUCT-2.                 
           MOVE SUB-STRUCT-1N TO FIELD-A OF STRUCT-1      
           MOVE SUB-STRUCT-2N TO FIELD-B OF STRUCT-1      
           DISPLAY "SUB-STRUCT-1  : " SUB-STRUCT-1        
           DISPLAY "SUB-STRUCT-2  : " SUB-STRUCT-2        
           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 

Осторожно: перемещение данных персонажа в поле COMP-3 может дать вам страшное исключение данных SOC7, когда ссылка на принимающий элемент ссылается. Это связано с тем, что не все битовые комбинации являются действительными числами COMP-3.

2 голосов
/ 21 июля 2010

У вас 2 проблемы.

COBOL имеет несколько числовых структур данных. У каждого свой набор правил.

Для УПАКОВАННОЙ ДЕЦИМАЛИ (КОМП-3)
• Числовые компоненты предложения PIC ВСЕГДА должны суммироваться с числом ODD. • Десятичный маркер «V» определяет расположение десятичной точки. • Отдельные элементы MOVE и математические функции будут поддерживать выравнивание десятичных значений - возможно как усечение высокого, так и низкого уровня. • Преобразование числовых типов данных (десятичная зона в упакованные и двоичные в упакованные) выполняется для вас.

например. S9 (5) V9 (2) COMP-3.
в том числе 2 десятичных знака> Длина рассчитывается как ROUND UP [(7 + 1) / 2] = 4 байта

     S9(6)V9(2) COMP-3.                                            

включая 2 десятичных знака> Длина рассчитывается как ROUND UP [(8 + 1) / 2] = 5 байтов Но 1 ½ байта не адресуется

Последний ½ байта полей COMP-3 является шестнадцатеричным представлением знака.
Значения знака ½ байта: C = положительный знак D = отрицательный знак F = без знака (не COBOL).

S9 (6) V9 (3) COMP-3 ЗНАЧЕНИЕ 123.45. Длина рассчитывается как ROUND UP [(9 + 1) / 2] = 5 байтов
Содержит X’00 01 23 45 0C ’
Обратите внимание на десятичное выравнивание и заполнение нулями.


Правила MOVE на уровне группы

COBOL Структуры полей данных определяются как иерархические структуры.

Поле группы 01 H-L - & любое поле уровня подгруппы -

  1. Почти всегда подразумеваемое строковое значение CHARACTER
  2. Если поле отдельного элемента имеет уровень 01 или 77 - оно может быть числовым.
  3. Поля отдельных элементов, определенные как числовые значения на уровне группы или подгруппы, будут обрабатываться как числовые, если на них ссылаются как на поля отдельных элементов.
  4. Применяются числовые правила. о Правильно оправдать o десятичное место o pad H-L (½ байта) с нулями o Числовое преобразование типов данных

Поле приема MOVE или математических вычислений определяет, будет ли выполняться преобразование числовых данных.

Числовое преобразование данных Если вы ПЕРЕМЕЩАЕТЕ или выполняете математическое вычисление, используя любой тип поля отправки (группу или элемент), к любому принимающему отдельному полю элемента, определенному с помощью предложения числового PIC ---, тогда для получающего поля будет выполнено преобразование числовых данных. S0C7 происходит, когда нечисловые данные перемещаются в принимающее численно определенное поле ИЛИ, когда математические вычисления предпринимаются с использованием нечисловых данных.

Нет преобразования числовых данных Если вы переместите какой-либо тип поля (группу или элемент) в любое поле уровня группы или подгруппы, преобразование числовых данных НЕТ.
• Применяются правила перемещения персонажа.
• Левый Justify & pad с пробелами.

Это одна из основных причин нечисловых данных в числовом поле.

Одно из основных применений MOVE уровня отправляющей группы, содержащего поля числовых элементов, к уровню принимающей группы, содержащей поля числовых элементов (идентично сопоставленных), - для повторной инициализации полей числовых элементов с использованием 1 инструкции MOVE.

Очистка маски - или - MOVE распространения данных также возможна для очистки таблиц, где уровень группы таблиц превышает 255 байтов.

...