Русский
Русский
English
Статистика
Реклама

Перевод COBOL и 2020202,02

В прошлые годы, даже в последние год-два мне иногда попадались новости, что кому-то пришёл счёт или чек на смешную сумму 2020202 доллара и 02 цента.

Если вы такое увидите, то (почти наверняка) это ошибка программирования на COBOL. Большинство программистов COBOL совершают эту глупую ошибку, и я не исключение.

Проблема вызвана тем, как именно мы обычно инициализируем запись. Возьмём такую маленькую программу:

       identification division.       program-id.           mistake.              data division.       working-storage section.            * *** Input record, typically maintained on disk/tape somewhere.       01  dr-datarec.           03  dr-name                 pic x(20).           03  dr-amount               pic s9(7)v99, comp-3.      * *** print record, sent to a line printer.       01  dt-detail.           03  dt-name                 pic x(20).           03  filler                  pic x.           03  dt-amount               pic z,zzz,zz9.99.                          procedure division.                  move spaces                 to dr-datarec.           move "test"                 to dr-name.           move 100                    to dr-amount.           move spaces                 to dt-detail.           move dr-name                to dt-name.           move dr-amount              to dt-amount.           display dt-detail.                  stop run.

В этой программе входная запись dr-datarec. Обычно она идёт откуда-то с диска, но для этого простого теста создаётся вручную.

Как только получена входная запись, выполняются вычисления, а затем запись выводится с помощью dt-detail.

Проблема в том, как создаётся запись dr-datarec. Обратите внимание, как перемещаются пробелы для её инициализации. Это был типичный метод инициализации записи.

Таким образом, пробелы есть во всех полях PICX. Но! Все поля COMP-3 также инициализируются, только не до нуля. Программист должен быть уверен, что для всех полей COMP-3 создаются допустимые значения. В тестовой программе это делается правильно:

           move spaces                 to dr-datarec.           move "test"                 to dr-name.           move 100                    to dr-amount.

В поле dr-amount явно есть 100. После запуска получается:

./mistake test                       100.00

Что делать, если допущена ошибка кодирования и запись dr-amount не инициализирована должным образом?

Там всё ещё есть пробелы ASCII. Это шестнадцатеричное значение 20 или двоичное 0010 0000.

COMP-3 хранит цифры в виде четырёхбитных нибблов, поэтому один пробел отображается как 20. Если у вас 9 цифр, как у dr-amount, то для этого требуется 10 нибблов памяти (9 нибблов для цифр и один для знака) или 5 байт.

Перемещение пробелов в dr-datarec приведёт к тому, что в это поле сохранится 5 пробелов или шестнадцатеричное значение 2020202020. Если попытаться использовать неинициализированную переменную, это интерпретируется как 2020202,02.

Если закомментировать инициализацию dr-amount, то можно принудительно вызвать эту ошибку:

           move spaces                 to dr-datarec.           move "test"                 to dr-name.     *     move 100                    to dr-amount.

Теперь при запуске программы:

./mistake test                 2,020,202.02

Чтобы исправить эту проблему, COBOL 85 ввёл глагол INITIALIZE. Вместо перемещения пробелов в запись вы её инициализируете, а она переместит пробелы в буквенно-цифровые поля, а нули в числовые:

      *    move spaces                 to dr-datarec.           initialize dt-detail.           move "test"                 to dr-name.      *    move 100                    to dr-amount.

Результат выполнения:

./mistake test                         0.00

Так что в следующий раз, когда увидите бедную вдову, которой пришёл счёт за коммунальные услуги $2020202,02, вы будете точно знать, что произошло!
Источник: habr.com
К списку статей
Опубликовано: 05.11.2020 20:23:57
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Cobol

Программирование

Ошибка

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru