Suponha que você precise representar os valores indicados nos itens abaixo em um programa escrito na Linguagem C. Indique o tipo de dado mais adequado para cada caso, explicando o porquê da escolha.
Valores monetários de depósitos e saques em uma conta corrente

Passo 1

O enunciado pede: escolher o tipo de dado em C mais adequado para representar “valores monetários de depósitos e saques em uma conta corrente” e justificar a escolha.
Informações/condições importantes que extraem do enunciado:
  • Os valores são monetários (têm casas decimais, normalmente centavos).
  • Precisam ser representados exatamente (sem erros de arredondamento que prejudiquem somas/subtrações de dinheiro).
  • Devem permitir operações comuns: soma, subtração, comparação, possivelmente multiplicação/divisão por inteiros (ex.: múltiplas parcelas) ou por taxas (a tratar com cuidado).
  • Devem suportar valores negativos (saques) e positivos (depósitos).

Passo 2

Por que precisamos pensar com cuidado: algumas representações causam imprecisão numérica. É importante entender o que “representar exatamente” quer dizer aqui. Quando falamos de dinheiro, normalmente queremos que, por exemplo, R\$12,34 seja armazenado e depois somado/subtraído sem aparecerem erros do tipo R\$ 12,3399999999 ou R\$ 12,3400000001. Esses pequenos erros acontecem com tipos de ponto flutuante porque números decimais como 0,1 não têm representação finita em base binária — e o computador usa base binária para floats/doubles.

Passo 3

Por que não usar float/double/long double em C para dinheiro (explicação didática):
  • Tipos de ponto flutuante representam números em base 2 (binário). Algumas frações decimais simples, por exemplo 0,1 (dez centavos), tornam-se periódicas em binário, então o valor armazenado é uma aproximação.
  • Aproximações geram erros acumulados em somas e comparações; em aplicações financeiras isso pode levar a centavos a mais/menos.
  • Exemplos práticos: operações como somar 0,10 e 0,20 em double podem não resultar exatamente em 0,30 por causa de arredondamento binário. Portanto, não é recomendável para valores que exigem exatidão decimal.

Passo 4

Solução prática e didática: usar aritmética inteira em centavos (unidade mais baixa). Ideia: representar todos os valores monetários como inteiro que conta centavos (ou a menor unidade usada). Assim não há representação periódica: é inteiro, exato. Fórmula de conversão (explicada passo-a-passo):
  • Se você tem um valor em reais com centavos, chame-o de v_{\text{reais}}.
  • Armazene internamente como inteiro de centavos v_{\text{centavos}} dado por
v_{\text{centavos}} = \text{round}(v_{\text{reais}} \times 100)
(onde \text{round} é arredondamento apropriado se estiver convertendo a partir de entrada em ponto flutuante; idealmente parseie texto para evitar float intermediário).
  • Exemplo concreto: R\$ 12,34 \Rightarrow v_{\text{centavos}} = 12{,}34 \times 100 = 1234 (armazena-se o inteiro 1234).
  • Nas operações: soma e subtração são operações inteiras simples sobre v_{\text{centavos}}. Para apresentar ao usuário, converte-se de volta: dividir por 100 para reais e usar resto para centavos.

Passo 5

Qual tipo inteiro usar em C e por quê (tamanho e alcance):
  • int32_t (32 bits com sinal) tem máximo 2^{31}-1 = 2\,147\,483\,647 centavos, ou seja aproximadamente 21\,474\,836,47 reais. Dependendo do contexto (contas com grandes saldos ou sistemas bancários corporativos), isso pode ser insuficiente.
  • int64_t (64 bits com sinal) tem máximo aproximado 9{,}22\times 10^{18} centavos, que em reais é cerca de 9{,}22\times 10^{16} reais — um alcance extremamente grande para qualquer aplicação bancária típica.
  • Por isso a escolha prática e segura é usar um inteiro de 64 bits com sinal (em C normalmente int64_t do cabeçalho <stdint.h> ou long long quando int64_t não for usado explicitamente). Isso permite armazenar centavos, suportar sinais (positivo/negativo) e evitar overflow em cenários normais.

Passo 6

Como trabalhar em código (boas práticas rápidas e claras):
  • Armazenamento: usar int64_t saldo_centavos; onde saldo_centavos contém centavos.
  • Entrada: evitar ler valores monetários diretamente como double. Melhor parsear string do usuário (por exemplo “12,34” ou “12.34”), separar reais e centavos e construir o inteiro, ou usar leitura em centavos direta. Se usar conversão a partir de double, aplique arredondamento ao multiplicar por 100.
  • Saída: para exibir v_{\text{centavos}} como reais, faça divisão inteira por 100 para reais e resto para centavos: por exemplo reais = v_{\text{centavos}} / 100, centavos = |v_{\text{centavos}}| \% 100 e formate com sinal/zero à esquerda dos centavos.
  • Operações com percentuais/taxas: multiplicaçõess que resultem em fração de centavo exigem regras de arredondamento (arredondar para o centavo mais próximo ou truncar, conforme regra do negócio). Tecnica comum: usar inteiros com escala maior (por exemplo, trabalhar em milésimos de centavo ou usar multiplicação por inteiros e depois dividir com arredondamento) ou usar bibliotecas específicas de decimal quando operações complexas de juros são frequentes.
  • Negativos: representados naturalmente (saque = valor negativo em centavos).

Passo 7

Resumo/justificativa final (curta e prática): escolher um inteiro de 64 bits que represente centavos evita erros de ponto flutuante, permite operações exatas e possui alcance suficiente para aplicações reais. É simples, eficiente e seguro para depósitos/saques.

Resposta

Tipo: int64_t (ou long long) representando centavos (armazenar o valor em centavos como inteiro).
Por quê: evita erros de ponto flutuante (exatidão decimal), permite soma/subtração/comparação exatas, suporta negativos e tem alcance muito grande para valores monetários reais.

Exercícios relacionados