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:

COBOL: Representacao em memória de um campo do tipo COMP-3

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.