[Cobol] COBOL и $2 020 202,02 (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В прошлые годы, даже в последние год-два мне иногда попадались новости, что кому-то пришёл счёт или чек на смешную сумму 2 020 202 доллара… и 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. Обратите внимание, как перемещаются пробелы для её инициализации. Это был типичный метод инициализации записи.
Таким образом, пробелы есть во всех полях PIC X. Но! Все поля 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. Если попытаться использовать неинициализированную переменную, это интерпретируется как 2 020 202,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
Так что в следующий раз, когда увидите бедную вдову, которой пришёл счёт за коммунальные услуги $2 020 202,02, вы будете точно знать, что произошло!
===========
Источник:
habr.com
===========
===========
Автор оригинала: Big Dan the Blogging Man
===========Похожие новости:
- [Open source, Lisp, Функциональное программирование, Учебный процесс в IT, Искусственный интеллект] SRFI-216: Поддержка курса SICP. Обсудим?
- [Программирование, .NET, Промышленное программирование, Xamarin] XAML Aesthetics: Value Converters
- [Open source, Системное программирование, Программирование микроконтроллеров, Процессоры] О кэшах в микроконтроллерах ARM
- [C++] ConcurrentCpp — The C++ concurrency library
- [Программирование, .NET, Промышленное программирование, Xamarin] Эстетика XAML: конвертеры значений
- [Семантика, Программирование, Prolog, Бизнес-модели] Проектируем мульти-парадигменный язык программирования. Часть 3 — Обзор языков представления знаний
- [Промышленное программирование, Разработка робототехники, Программирование микроконтроллеров, Разработка для интернета вещей, Производство и разработка электроники] ModBus Slave RTU/ASCII без смс и регистрации
- [Функциональное программирование, Конференции, Elixir/Phoenix] Исследование экосистемы Elixir в СНГ 2020 и анонс очередного Elixir Meetup Online
- [Спортивное программирование, Хакатоны] «Вездекод»: как перенести хакатон в онлайн и не облажаться
- [Разработка веб-сайтов, JavaScript, Программирование] Управление памятью в JavaScript (перевод)
Теги для поиска: #_cobol, #_cobol, #_programmirovanie (программирование), #_oshibka (ошибка), #_cobol
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:40
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В прошлые годы, даже в последние год-два мне иногда попадались новости, что кому-то пришёл счёт или чек на смешную сумму 2 020 202 доллара… и 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. Обратите внимание, как перемещаются пробелы для её инициализации. Это был типичный метод инициализации записи. Таким образом, пробелы есть во всех полях PIC X. Но! Все поля 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. Если попытаться использовать неинициализированную переменную, это интерпретируется как 2 020 202,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 Так что в следующий раз, когда увидите бедную вдову, которой пришёл счёт за коммунальные услуги $2 020 202,02, вы будете точно знать, что произошло! =========== Источник: habr.com =========== =========== Автор оригинала: Big Dan the Blogging Man ===========Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:40
Часовой пояс: UTC + 5