O que é COMP-3 no COBOL? Entenda o Decimal Compactado
Se você trabalha com manutenção de sistemas COBOL, provavelmente já viu algo assim em um programa:
01 QT-VENDAS PIC 9(5).
01 VR-SALARIO PIC S9(6)V99 COMP-3.
Algumas variáveis são simplesmente numéricas (PIC 9(…)), enquanto outras aparecem com a cláusula COMP-3.
Em algum momento alguém provavelmente comentou que esse tipo de campo é compactado. E aí muita gente imagina que isso significa que ele é binário ou até ponto flutuante. E não é nada disso.
Então, afinal, o que é COMP-3 em COBOL?
COMP-3 é uma forma de armazenar números em decimal compactado (packed decimal), usada principalmente para economizar espaço e melhorar o desempenho de cálculos em sistemas corporativos.
Neste artigo, vou mostrar o que realmente significa o COMP-3, como o COBOL armazena esse tipo de campo, por que ele aparece com tanta frequência em sistemas corporativos e por que a escolha entre USAGE DISPLAY e USAGE COMP-3 pode ser uma decisão de arquitetura importante.
Variáveis numéricas do tipo DISPLAY
Vamos começar com o tipo mais simples de variável numérica em COBOL. Considere a seguinte declaração de variável:
01 WT-QT-VENDAS PIC 9(5).
Esse tipo de campo numérico é conhecido como decimal zonado ou DISPLAY. Tecnicamente, a declaração completa seria:
01 WT-QT-VENDAS PIC 9(5) USAGE IS DISPLAY.
Mas como DISPLAY é o padrão, normalmente essa parte não aparece no código.
Quando você define uma variável assim, está dizendo ao COBOL: “Quero armazenar um número de forma que ele possa ser exibido diretamente em telas, relatórios, arquivos texto e sysouts, sem necessidade de nenhuma conversão adicional”.
Como variáveis do tipo DISPLAY são armazenadas
Se colocarmos o valor 1932 nessa variável:
MOVE 1932 TO WT-QT-VENDAS
o COBOL reservará 5 bytes e armazenará um dígito em cada byte. Ou seja, quando o conteúdo for gravado em um arquivo ou exibido, ele aparecerá exatamente como 01932 que é o valor original armazenado.

Variáveis do tipo COMP-3: Decimal Compactado ou Packed Decimal
Agora vamos olhar para a declaração:
01 WT-QT-VENDAS PIC 9(5) USAGE IS COMP-3.
Ou, de forma simplificada:
01 WT-QT-VENDAS PIC 9(5) COMP-3.
Esse COMP-3 no COBOL significa COMPUTATIONAL-3, e poderia ser substituído por PACKED-DECIMAL:
01 WT-QT-VENDAS PIC 9(5) PACKED-DECIMAL.
Diferente do campo DISPLAY, o COBOL não usa um byte inteiro para cada dígito. Ele usa um nibble, a metade de um byte. Em outras palavras, apenas 4 bits dos 8 que compõem o byte.
Se colocarmos novamente o valor 1932 nessa variável, o armazenamento fica assim:

O último nibble é reservado para o sinal do número. Como o campo WT-QT-VENDAS foi criado sem sinal, o COBOL preencherá esse último nibble com um F.
Se fosse um campo sinalizado, do tipo…
01 WT-QT-VENDAS PIC S9(5) COMP-3.
…o último nibble teria sido preenchido com C (se o valor armazenado fosse positivo) ou D (se fosse negativo).
Ou seja, se você gravar esse campo em um arquivo e abrir esse arquivo com um editor de texto comum, você não verá o valor 01932 armazenado; o que aparecerá serão três bytes (não cinco), provavelmente sem representação legível nas tabelas ASCII e EBCDIC.
A única forma de saber qual o conteúdo real daquela variável é visualizando o arquivo em hexadecimal. Aí sim, você verá algo como:
01 93 2F
O que indica que o valor é 01932, sem sinal.
Por que COMP-3 é tão usado em sistemas corporativos
Existem três razões principais.
1) Economia de espaço: Um campo PIC 9(5) ocupa 5 bytes se for do tipo DISPLAY, e 3 bytes se for do tipo COMP-3. Se a picture fosse 9(13)v9(2), muito usada em valores financeiros, a diferença seria maior: 15 bytes no caso do DISPLAY contra 8 bytes no caso do COMP-3. Parece pouco, mas em sistemas que processam centenas de milhões de registros por dia, essa economia é enorme, mesmo nos dias de hoje.
2) Melhor desempenho em cálculos: O mainframe (e consequentemente o COBOL) é mais eficiente para operar com campos numéricos de ponto fixo do que com campos de ponto flutuante. Campos COMP-3 são armazenados em um formato que o COBOL consegue manipular mais rapidamente em operações aritméticas. Em um ambiente em que tudo é pensado para obter performance máxima, isso também faz a diferença.
3) Precisão numérica: Campos de ponto flutuante podem introduzir problemas de arredondamento e precisão, principalmente em sistemas que são intensivos em cálculo (veja também como o COBOL trabalha com campos de ponto flutuante). Para sistemas que operam com saldos bancários, salários, descontos, juros e multas, essa imprecisão é inaceitável. Campos de ponto fixo como o COMP-3, no entanto, oferecem precisão decimal exata nesse tipo de plataforma.
Conclusão
Se o COMP-3 é melhor em vários aspectos, por que nem tudo é definido assim? Porque nem todos os campos precisam disso.
Muitas vezes o analista decide manter um campo como DISPLAY porque ele não será usado em cálculos, é útil enxergá-lo diretamente no arquivo para facilitar depuração e auditoria, ou mesmo para poder enviá-lo para outras linguagens e plataformas que não sabem trabalhar com o decimal compactado.
Assim, dentro do mesmo arquivo, em um mesmo programa, você encontrará frequentemente campos DISPLAY para leitura humana ou integração entre plataformas, e COMP-3 para cálculos intensivos.
Campos do tipo COMP-3, portanto, não são nem binary nem float.
Se você quiser saber como declarar campos realmente binários em COBOL, dê uma olhada nesse artigo.
Para entender como o COBOL trabalha com campos de ponto flutuante (e por que eles são tão pouco usados em sistemas comerciais), dê uma olhada nesse outro artigo.
A escolha do tipo certo para o objetivo certo faz parte do conjunto de decisões de arquitetura de uma aplicação.
