| Bellacosa Mainframe analisa as variaveis estilo cobol |
☕ Um Café no Bellacosa Mainframe
Muito Além do PIC S9(7)V99 COMP-3
O Que Todo Programador COBOL Padawan Precisa Saber Sobre a Anatomia de uma Variável, Como o IBM Z Enxerga Seus Dados e Por Que Essa Sintaxe Continua Dominando o Mundo Financeiro
"Qual é a variável mais importante do COBOL?"
A maioria dos programadores iniciantes responde algo como:
"WS-NOME."
Ou talvez:
"WS-SALARIO."
Mas essa pergunta possui uma resposta muito mais interessante.
A variável mais importante do COBOL não é uma variável específica.
É o conceito por trás de todas elas.
Uma simples declaração como esta:
05 WS-MONTANTE PIC S9(7)V99 COMP-3.
parece pequena.
São apenas alguns caracteres.
Entretanto, essa única linha descreve muito mais informações do que praticamente qualquer linguagem moderna consegue expressar de forma tão compacta.
Ela informa ao compilador:
onde o dado pertence;
qual seu significado;
como será armazenado;
como será processado pela CPU;
quanto espaço ocupará;
se aceita números negativos;
onde está a posição decimal;
como será gravado em disco;
como será enviado ao DB2;
como participará das operações matemáticas.
Em outras palavras...
Ela descreve completamente a vida daquele dado.
Hoje vamos abrir essa declaração como um engenheiro desmonta um motor Rolls-Royce.
Pegue seu café.
Vamos viajar para dentro da memória do IBM Z.
| Bellacosa Mainframe e a anatomia de uma variavel |
COBOL pensa diferente
Quem vem de Java, Python, C# ou JavaScript costuma enxergar uma variável assim:
double salario;
ou
salario = 1500.50
Pronto.
Acabou.
Mas o COBOL nasceu em uma época completamente diferente.
Na década de 60 memória era absurdamente cara.
Processadores eram lentos.
Discos eram pequenos.
Cada byte economizado representava milhares de dólares.
Por isso o COBOL não pergunta apenas:
"Que tipo de variável é essa?"
Ele pergunta:
"Como exatamente esse dado existirá dentro do computador?"
Essa filosofia mudou toda a arquitetura da linguagem.
Primeiro elemento: o nível
05 WS-MONTANTE ...
O número 05 não possui absolutamente nenhuma relação com tamanho.
Ele representa hierarquia.
Imagine um organograma de uma empresa.
Empresa
Financeiro
Contabilidade
Funcionários
O COBOL organiza dados exatamente assim.
Exemplo:
01 CLIENTE.
05 DADOS-PESSOAIS.
10 NOME.
10 CPF.
05 DADOS-FINANCEIROS.
10 LIMITE.
10 SALDO.
Visualmente:
CLIENTE
│
├── DADOS-PESSOAIS
│ ├── NOME
│ └── CPF
│
└── DADOS-FINANCEIROS
├── LIMITE
└── SALDO
Percebe?
O COBOL constrói verdadeiras árvores de dados.
É uma linguagem extremamente orientada à estrutura.
Muito antes de XML.
Muito antes de JSON.
Muito antes de objetos.
O nome importa muito
Observe:
WS-MONTANTE
Isso não é apenas um identificador.
É documentação.
Durante décadas milhares de desenvolvedores trabalharam simultaneamente no mesmo sistema.
Ninguém tinha IDE colorida.
Não existia autocomplete.
Então surgiram convenções.
Por exemplo:
WS-
significa:
Working-Storage
Já:
LS-
é Local Storage.
LK-
Linkage.
SQL-
variáveis utilizadas pelo DB2.
DFH-
estruturas do CICS.
Quando você vê um nome começando por WS-, imediatamente sabe onde aquela variável foi declarada.
Isso aumenta muito a legibilidade.
O verdadeiro coração da declaração
Chegamos ao famoso:
PIC
PIC significa:
Picture
Muitos imaginam que ele define apenas o tamanho.
Não.
Ele descreve a forma como o dado será representado.
É quase um DNA.
Vamos ver alguns exemplos.
Texto:
PIC X(30)
Trinta caracteres.
Somente letras:
PIC A(20)
Numérico:
PIC 9(8)
Numérico com casas decimais:
PIC 9(7)V99
Editado para impressão:
PIC $$$,$$9.99
Cada Picture possui uma finalidade diferente.
O significado do "9"
Na nossa variável aparece:
9(7)
O nove significa:
um dígito decimal.
Logo:
9
aceita:
0 até 9
Enquanto
99
aceita
00 até 99
Já
9(7)
é apenas uma forma elegante de escrever:
9999999
Ou seja:
sete dígitos.
Nada mais.
Nada menos.
O misterioso S
Agora observe:
S9(7)
O "S" significa:
Signed.
Número com sinal.
Sem ele:
0
até
9999999
Com ele:
-9999999
até
+9999999
Mas aqui existe uma curiosidade interessante.
O sinal normalmente não ocupa um byte inteiro.
No formato COMP-3 ele é armazenado dentro do último nibble do número.
Uma solução extremamente elegante criada quando memória era um recurso precioso.
A genialidade da vírgula invisível
Agora chegamos ao personagem mais incompreendido do COBOL.
A letra:
V
A maioria dos iniciantes acredita que ela representa uma vírgula.
Na realidade...
Ela representa a posição lógica da vírgula.
A vírgula nunca é gravada.
Nunca.
Suponha:
PIC 9(5)V99
Na memória teremos:
1234567
Mas o COBOL interpreta como:
12345,67
Onde foi parar a vírgula?
Ela nunca existiu.
O compilador apenas sabe que, ao interpretar aquele número, deve considerar duas casas decimais.
Parece um detalhe.
Mas imagine milhões de registros.
Economizar um byte em cada registro significava reduzir discos inteiros.
A importância da precisão
Vamos comparar.
Python:
0.1 + 0.2
Resultado:
0.30000000000000004
Não é erro do Python.
É matemática binária.
Agora veja o COBOL usando Packed Decimal.
0.10
+
0.20
=
0.30
Sempre.
Sem aproximações.
Sem surpresas.
Sem arredondamentos inesperados.
É exatamente por isso que bancos utilizam COMP-3 há décadas.
Dinheiro exige precisão absoluta.
O que é COMP-3?
Agora chegamos ao astro da declaração.
COMP-3
Também conhecido como:
Packed Decimal.
BCD.
Decimal Empacotado.
Ao contrário do DISPLAY, onde cada dígito ocupa um byte inteiro, o COMP-3 armazena dois dígitos por byte.
Cada dígito utiliza apenas quatro bits.
Ou seja:
12
cabe em um único byte.
Muito mais eficiente.
Como o número fica na memória?
Suponha:
123456789
Em DISPLAY:
F1 F2 F3 F4 F5 F6 F7 F8 F9
Nove bytes.
No COMP-3:
12 34 56 78 9C
Cinco bytes.
O "C" representa positivo.
Se fosse negativo:
9D
Essa codificação ainda hoje é utilizada por praticamente todos os grandes bancos do planeta.
Quantos bytes essa variável ocupa?
Existe uma fórmula famosa.
(dígitos + 2) / 2
Arredondando para cima.
Nossa variável possui:
7
+
2
=
9 dígitos
Logo:
(9 + 2) / 2
=
5 bytes
Apenas cinco bytes.
Parece pouco?
Imagine um cadastro contendo:
300 milhões
de clientes.
Economizar quatro bytes por registro significa aproximadamente:
1,2 GB
Apenas em um campo.
Agora multiplique isso por centenas de campos.
Depois por milhares de tabelas.
Depois por backups.
Depois por replicações.
Agora você entende por que arquitetos de mainframe pensam diferente.
O compilador faz muito mais do que imaginamos
Quando escrevemos:
05 WS-MONTANTE PIC S9(7)V99 COMP-3.
Nós enxergamos apenas texto.
O compilador enxerga uma enorme quantidade de metadados.
Ele sabe:
✔ É numérico.
✔ É decimal.
✔ Possui sinal.
✔ Tem duas casas decimais.
✔ Ocupa cinco bytes.
✔ Pode participar de operações aritméticas.
✔ Será armazenado em Packed Decimal.
✔ É compatível com DECIMAL do DB2.
✔ Pode ser usado em comandos ADD, SUBTRACT, MULTIPLY e COMPUTE.
Tudo isso antes mesmo do programa começar a executar.
Por que DB2 gosta tanto de COMP-3?
Observe esta coluna SQL.
SALDO DECIMAL(9,2)
Em COBOL normalmente teremos:
PIC S9(7)V99 COMP-3
Os dois formatos representam exatamente o mesmo conceito.
Resultado?
Conversões mínimas.
Mais velocidade.
Menor consumo de CPU.
Menor custo operacional.
VSAM, IMS e CICS também entendem esse formato
Quando um programa COBOL grava um registro VSAM contendo COMP-3, os números são gravados exatamente nesse formato empacotado.
Quando outro programa COBOL lê esse registro, nenhuma conversão é necessária.
Tudo continua extremamente eficiente.
Por isso sistemas desenvolvidos há quarenta anos continuam rápidos até hoje.
O preço dessa eficiência
Existe um lado curioso.
Abra um arquivo contendo COMP-3 em um editor hexadecimal.
Você verá algo parecido com:
12 34 56 7C
Não parece um número.
Porque não é texto.
É uma representação física otimizada.
Por isso ferramentas modernas precisam converter esses bytes antes de exibi-los.
E quando falamos em APIs REST?
Hoje muitas aplicações COBOL conversam com Java, Python, Node.js e microsserviços.
Entretanto JSON não entende Packed Decimal.
Então ocorre uma conversão.
Internamente:
12 34 56 7C
Externamente:
{
"saldo": 12345.67
}
É exatamente esse trabalho que tecnologias como IBM z/OS Connect, CICS Web Services e diversos frameworks de integração realizam.
Eles traduzem o universo do IBM Z para um formato compreendido pelas aplicações modernas, preservando a precisão decimal do COBOL.
Uma lição para o Programador Padawan
Talvez você esteja pensando:
"Tudo isso para declarar uma variável?"
Exatamente.
Essa é a beleza do COBOL.
Em linguagens modernas, muitas decisões ficam escondidas dentro da máquina virtual, do compilador ou da biblioteca de execução.
No COBOL, elas são explícitas.
O programador descreve com precisão quase cirúrgica como seus dados devem existir.
Essa filosofia nasceu da necessidade, mas transformou-se em uma das maiores virtudes da linguagem.
Não é por acaso que os maiores bancos, seguradoras, bolsas de valores e órgãos governamentais do mundo continuam confiando no IBM Z para processar trilhões de dólares diariamente.
Quando um PIX é liquidado, um cartão é autorizado, um financiamento é calculado ou uma aposentadoria é paga, há uma grande chance de que, em algum ponto dessa jornada, exista uma variável muito parecida com a nossa velha conhecida:
05 WS-MONTANTE PIC S9(7)V99 COMP-3.
Ela pode parecer simples.
Mas dentro dela vivem mais de seis décadas de engenharia, otimização, compatibilidade e confiabilidade.
E talvez essa seja a maior lição para todo Programador Padawan: no universo do Mainframe, uma linha de código raramente faz apenas uma coisa. Cada declaração carrega décadas de experiência acumulada, decisões arquiteturais cuidadosamente pensadas e um compromisso absoluto com precisão, desempenho e estabilidade. Aprender a "ler" uma variável COBOL é aprender a enxergar a lógica invisível que sustenta alguns dos sistemas mais críticos do planeta. Quando você dominar essa linguagem dos dados, deixará de apenas escrever programas e passará a compreender como o IBM Z realmente pensa.