Буквенно-цифровой переход к цифровому

Буквенно-цифровое перемещение к числовой переменной привело к неожиданным результатам. Вот код fyr:

  DATA DIVISION.                                 
  WORKING-STORAGE SECTION.                       
  01  WS-VAR-STR       PIC X(3) VALUE SPACES.                
  01  WS-VAR-NUM       PIC 9(3) VALUE ZEROES. 
  PROCEDURE DIVISION.                            
      MOVE '1'         TO WS-VAR-STR                  
      MOVE WS-VAR-STR  TO WS-VAR-NUM
      DISPLAY 'STRING > ' WS-VAR-STR '< MOVED > ' WS-VAR-NUM '<'

      IF WS-VAR-NUM >= 40 AND <= 59
         DISPLAY 'INSIDE IF >' WS-VAR-NUM
      ELSE 
         DISPLAY 'INSIDE ELSE >' WS-VAR-NUM
      END-IF
      GOBACK                                     
      .  

    OUTPUT:
    STRING > 1  < MOVED > 1 0<
    INSIDE ELSE >1 O

Результат странный, и я хочу понять, почему «1» перемещается как «1 0» в числовую переменную, и, что интересно, не было никаких проблем с его обработкой. Делитесь своими взглядами. Спасибо за интерес.


person Raja Reddy    schedule 26.05.2011    source источник
comment
Я бы проверил, не является ли это ошибкой DISPLAY (или функцией). Попробуйте написать IF WS-VAR-NUM EQUAL 1 THEN ..., чтобы проверить реальный контент.   -  person Dr. belisarius    schedule 26.05.2011
comment
Попробуйте MOVE '001' в WS-VAR-STR. Переместить '1' в WS-VAR-STR переместит '1'. Move не выполняет преобразование типов.   -  person tonyriddle    schedule 26.05.2011
comment
@tony См., например, это tek-tips.com/viewthread.cfm?qid= 705710   -  person Dr. belisarius    schedule 26.05.2011
comment
@belisarius Подпрограмма convert по предоставленной вами ссылке - это то, как мы это сделали. Он удаляет нечисловые символы, выравнивает числовые символы по правому краю, а поле дополняется нулями. Затем этот результат можно переместить в числовое поле.   -  person tonyriddle    schedule 26.05.2011


Ответы (1)


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

Чего вы ожидали в результате?

Перенос буквенно-цифровых полей в числовые осуществляется без «преобразования». По сути, вы просто вставили одну цифру, за которой следуют два пробела, в числовое поле. "1" было в порядке, два пробела - нет. Последние два байта WS-VAR-NUM содержат пробелы.

Но подождите... почему последний символ - ноль? Ответ на этот вопрос немного сложнее. Элементы, объявленные как PIC 9 something, представлены в Zoned Decimal. Каждая цифра зонированного десятичного числа представлена ​​одним байтом. 4 старших бита каждого байта являются битами зоны; 4 старших бита младшего байта представляют собой знак элемента. 4 младших бита каждого байта содержат значение цифры. Ключевым моментом здесь является то, где хранится знак. Он находится в старших битах последнего байта. В вашем объявлении не было знака, поэтому оператор MOVE сбрасывает биты знака и заменяет их числовыми старшими битами по умолчанию (помните, что единственными допустимыми символами для MOVE являются цифры, поэтому этот процесс исправления всегда должен давать правильный результат). Старшие биты зонированной десятичной цифры без знака всегда HEX F. Каковы младшие биты последнего байта? Пробел имеет двоично-десятичное шестнадцатеричное значение 40. Ноль — это шестнадцатеричное значение F0. Поскольку оператор MOVE «исправляет» знак автоматически, вы получите HEX F0 в младшем разряде, который, как вы уже догадались, равен нулю. Ни одна из других «цифр» не содержит битов знака, поэтому они остаются такими, какими они были.

Наконец, оператор DISPLAY преобразует зонированные десятичные поля в их эквивалентное символьное представление для представления: Чистый результат: '1 0'.

Кстати Выше обсуждалось, как это работает на платформе IBM z/OS — другие наборы символов (например, ASCII) и/или другие платформы могут давать другие результаты, а не потому, что IBM делает что-то не так. , а потому, что программа выполняет недопустимое MOVE и результаты по существу не определены.

person NealB    schedule 26.05.2011
comment
Спасибо за такое терпеливое и кристально ясное объяснение, хотя очевидно, что я сделал неправильный ход. Также спасибо за понимание моего намерения выяснить причину результата после такого движения. Вы ссылались на что-то, чтобы понять это, если да, поделитесь этим ценным материалом... это действительно достойно! - person Raja Reddy; 30.05.2011