Se você vir isso, é (quase certamente) um erro de programação COBOL. A maioria dos programadores COBOL comete esse erro estúpido, e não sou exceção.
O problema é causado pela maneira como geralmente inicializamos o registro. Vamos pegar um pequeno programa como este:
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.
Neste programa, o registro de entrada
dr-datarec
. Normalmente vem de algum lugar no disco, mas para este teste simples, é criado manualmente.
Assim que um registro de entrada é recebido, o cálculo é executado e, em seguida, o registro é enviado usando
dt-detail
.
O problema é como o registro é criado
dr-datarec
. Observe como os espaços são movidos para inicializá-lo. Este era o método típico para inicializar um registro.
Assim, existem espaços em todos os campos PIC X. Mas! Todos os campos COMP-3 também são inicializados, mas não para zero. O programador deve ter certeza de que valores válidos são gerados para todos os campos COMP-3. O programa de teste faz certo:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
Há
dr-amount
claramente 100 no campo. Depois de começar, verifica-se:
./mistake
test 100.00
E se houver um erro de codificação e o registro
dr-amount
não for inicializado corretamente?
Ainda há espaços ASCII lá. Este é um valor hexadecimal de 20 ou binário 0010 0000.
COMP-3 armazena dígitos como nibbles de quatro bits, então um espaço é exibido como 20. Se você tiver 9 dígitos como dr-amount, então isso requer 10 nibbles de memória (9 nibbles para dígitos e um para sinal) ou 5 bytes.
Mover espaços
dr-datarec
resultará em 5 espaços ou o valor hexadecimal 2020202020 sendo armazenado neste campo. Se você tentar usar uma variável não inicializada, ela será interpretada como 2020 202.02.
Se você comentar a inicialização
dr-amount
, pode forçar este erro:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
Agora, ao iniciar o programa:
./mistake
test 2,020,202.02
Para corrigir esse problema, o COBOL 85 introduziu o verbo INITIALIZE. Em vez de mover espaços para um registro, você o inicializa e ele move espaços para campos alfanuméricos e zeros para campos numéricos:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
Resultado da execução:
./mistake
test 0.00
Portanto, da próxima vez que vir uma viúva pobre que recebeu uma conta de serviços públicos de $ 2.020.202,02, você saberá exatamente o que aconteceu!