Расшифровать двоично-десятичный код
У меня есть поле pic X(03) с датой в формате X'160101'в формате ггмдд.
Я хотел бы знать, как преобразовать его в рис х (06).
До сих пор я пытался переместить его обратно в 9(03) и переместить 9(03) в 9(06), но это не сработало.
Как я могу это сделать?
2 ответа
Если вы выполняете поиск в стеке, вы должны найти ответ (на этот вопрос уже был дан ответ).
Но создайте поля наподобие (my-date-x содержит дату):
03 my-date-x pic x(3).
03 my-date-9 pic 9(6).
03 date-ymdv0 pic 9(6)v9 comp-3.
03 date-x pic x(3) redefines date-ymdv0.
И код
Move 0 to date-ymdv0
Move my-date-x to date-x
Move date-ymdv0 to my-date-9
Причина, по которой он работает, заключается в том, что 9 (6) v9 comp3 160101 хранится как x'1601010c', что и есть (+ 0c в конце).
То, что у вас есть, является двоично-десятичным (BCD). То есть данные хранятся в двоичном поле, но это значение является десятичным представлением, а не двоичным, что важно для значения. X'160101'в будет 1,442,049. X'160201'будет 1,442,305. Поэтому, если бы вы смогли обработать его как двоичное поле (вам нужно было бы добавить двоичный ноль, чтобы сделать его правильной длиной для двоичного поля), вам пришлось бы сделать несколько глупых вычислений.
Таким образом, вы делаете что-то другое, и проще. BCD не является родным типом данных COBOL. PACKED-DECIMAL (часто такой же, как COMP-3/COMPUTATIONAL-3) - это тип BCD, который включает значение знака в младшем (самом правом) полубайте. Так что не совсем BCD, но вы можете рассматривать ваш BCD как DECIMAL в упаковке: вот так:
01 BCD-TO-PACKED.
05 BTP-SOURCE-BCD PIC XXX.
05 BTP-PACKED-ZERO PACKED-DECIMAL PIC 9 VALUE ZERO.
01 FILLER
REDEFINES BCD-TO-PACKED.
05 BTP-PACKED-TO-MOVE
PAKCED-DECIMAL PIC 9(6)V9.
01 DATE-AS-PIC-X PIC X(6).
01 DATA-AS-CHARACTER-NUMERIC
REDEFINES DATE-AS-PIC-X PIC 9(6).
MOVE your-source-value TO BTP-SOURCE-BCD
MOVE BTP-PACKED-TO-MOVE TO DATA-AS-CHARACTER-NUMERIC
После этого вы можете с радостью ссылаться на DATE-AS-PIC-X и делать с ним все, что захотите.
BCD-TO-PACKED - это четырехбайтовое групповое поле, которое, благодаря предложению VALUE и ничему не меняющемуся, имеет в последнем случае X'0F'. Это десятичное поле без знака с одной цифрой и нулевым значением.
Затем вы делаете X-to-X MOVE для BTP-SOURCE-BCD. BCD-TO-PACKED теперь выглядит так: X'1601010F'. Что совершенно верно для упакованного десятичного поля. Вы могли бы разделить это на 10, чтобы получить вашу дату (УТОЧНЯЕТ это как PACKED-DECIMAL PIC 9(7)), но зачем тратить ЦП?
Вместо этого, в переопределении вы определяете одно десятичное место (V9). Когда компилятор генерирует код для ПЕРЕМЕЩЕНИЯ этого в другое числовое поле без десятичных разрядов, исходные десятичные разряды просто отбрасываются. Presto! Разделите на 10 без деления.
Примечание: выбранные имена данных должны помочь в объяснении. Вы должны сделать ваши данные значимыми, а не просто использовать "банальные" имена. "Числовой символ" называется ИСПОЛЬЗОВАНИЕ ИСПОЛЬЗОВАНИЯ в COBOL, это значение по умолчанию, если не указано ИСПОЛЬЗОВАНИЕ. Слово ИСПОЛЬЗОВАНИЕ редко используется само по себе. Таким образом, USAGE DISPLAY - это то, что у вас есть, когда есть поле PIC X или PIC 9 без другого использования.
Примечание: вы, вероятно, не должны использовать двухзначные годы. Вы не сможете иметь дело с датами ранее, чем 2000 или позже, чем 2199. Историческое использование двузначных лет было связано с дорогим дисковым хранилищем и "избыточностью данных" (все значения столетия были 19, так почему держите значение 19 80 разное время для одного и того же аккаунта). Если используются двузначные годы, убедитесь, что где-то есть что-то, имеющее отношение к столетию.
Примечание. Если вы попытаетесь переместить поле PIC X в числовое поле, компилятор предположит, что в этом поле есть допустимые номера символов, что является одной из причин, по которым ваша первоначальная попытка не удалась.