Pular para o conteúdo
Tutoriais

Integer Overflow: Guia Completo com Exemplos

Overflow de inteiro derrubou o Ariane 5 e continua causando bugs silenciosos no seu codigo. Veja como cada linguagem lida com isso e o que fazer pra se proteger.

Overflow nao e coisa do passado

Integer Overflow: Guia Completo com Exemplos. Overflow de inteiro derrubou o Ariane 5 e continua causando bugs silenciosos no seu codigo. Veja como cada linguagem lida com isso e o que fazer pra se proteger.

O que e overflow de inteiro (e por que voce deveria se importar)

Overflow de inteiro acontece quando uma operacao matematica produz um resultado que nao cabe no espaco reservado pra aquele tipo numerico. Imagina um velocimetro de carro que vai ate 999 km/h. Se voce tentar mostrar 1000, o que acontece? Depende do sistema. Alguns voltam pra 0. Outros mostram lixo. Outros travam.

Em computacao, cada tipo numerico tem um tamanho fixo. Um inteiro de 16 bits armazena valores de -32.768 ate 32.767. Se voce tentar guardar 32.768, o valor 'da a volta' e vira -32.768. Isso e exatamente o que aconteceu no Ariane 5 — o sistema de navegacao converteu um float de 64 bits pra int de 16 bits, o valor estourou o limite, e o foguete interpretou o numero absurdo como uma correcao de trajetoria legitima.

O perigo do overflow e que ele e silencioso. Na maioria das linguagens, nao lanca excecao. O programa continua rodando com dados corrompidos. E bugs de dados corrompidos sao os mais dificeis de debugar porque tudo parece funcionar — ate que nao funciona.

JavaScript: MAX_SAFE_INTEGER e a armadilha do IEEE 754

JavaScript nao tem tipo inteiro. Todo numero e um IEEE 754 double-precision float de 64 bits. Isso significa que JS consegue representar numeros inteiros com precisao ate 2^53 - 1, que e o famoso Number.MAX_SAFE_INTEGER (9.007.199.254.740.991). Acima disso, JS comeca a pular numeros.

javascript
// O problema em acao
console.log(Number.MAX_SAFE_INTEGER);       // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1);   // 9007199254740992 (ok)
console.log(Number.MAX_SAFE_INTEGER + 2);   // 9007199254740992 (ERRADO! deveria ser ...993)
console.log(Number.MAX_SAFE_INTEGER + 3);   // 9007199254740994 (ERRADO!)
console.log(Number.MAX_SAFE_INTEGER + 4);   // 9007199254740996 (ERRADO!)

// Comparacao que deveria ser false retorna true
console.log(9007199254740992 === 9007199254740993); // true (!)

// Verificando se um numero e seguro
console.log(Number.isSafeInteger(9007199254740991)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false

Percebe o problema? JS nao lanca erro. Ele simplesmente arredonda pro numero representavel mais proximo. Se voce ta somando valores financeiros, calculando IDs sequenciais ou comparando timestamps em nanosegundos, isso e uma bomba-relogio.

A solucao no JavaScript moderno e o BigInt, introduzido no ES2020. BigInt lida com inteiros de tamanho arbitrario — nao tem limite. Mas tem pegadinhas.

javascript
// BigInt basico
const grande = 9007199254740993n; // o 'n' no final cria um BigInt
console.log(grande);               // 9007199254740993n (correto!)

// Operacoes entre BigInt
console.log(grande + 1n);          // 9007199254740994n
console.log(grande * 2n);          // 18014398509481986n

// ERRO: nao pode misturar BigInt com Number
// console.log(grande + 1);        // TypeError!

// Conversao explicita
console.log(grande + BigInt(1));   // funciona
console.log(Number(grande));       // 9007199254740992 (perde precisao!)

// JSON.stringify nao suporta BigInt nativamente
// JSON.stringify({ id: grande }); // TypeError!
// Solucao:
JSON.stringify({ id: grande.toString() }); // funciona

BigInt resolve o overflow, mas cria novos problemas: nao funciona com Math.max(), nao serializa direto em JSON, e nao pode ser misturado com Number em operacoes. Na pratica, voce precisa decidir na arquitetura do projeto onde vai usar BigInt e manter a consistencia.

Python: seguro por padrao, perigoso com NumPy

Python e a linguagem que mais protege o dev contra overflow — pelo menos no int nativo. O int do Python tem precisao arbitraria. Nao tem limite. Voce pode multiplicar numeros gigantescos e o Python aloca mais memoria conforme necessario.

python
# Python puro: sem overflow
x = 2 ** 1000
print(x)  # Numero com 302 digitos, tudo certo
print(type(x))  # <class 'int'>

# Operacoes com numeros enormes funcionam normalmente
print(2 ** 1000 + 1)  # Correto, sem perda de precisao

# Mas float tem os mesmos problemas do JavaScript
import sys
print(sys.float_info.max)  # 1.7976931348623157e+308
print(1.7976931348623157e+308 * 2)  # inf (overflow pra infinito)

Ate aqui, tudo lindo. Mas o perigo mora no NumPy. Quando voce usa NumPy, os inteiros voltam a ter tamanho fixo — e o overflow volta a ser silencioso.

python
import numpy as np

# NumPy int64: tem limite
a = np.int64(9223372036854775807)  # max int64
print(a + 1)  # -9223372036854775808 (OVERFLOW SILENCIOSO!)

# NumPy int32: limite menor ainda
b = np.int32(2147483647)  # max int32
print(b + 1)  # -2147483648 (OVERFLOW SILENCIOSO!)

# Protecao: usar errstate
with np.errstate(over='raise'):
    try:
        result = np.int64(9223372036854775807) + np.int64(1)
    except FloatingPointError:
        print('Overflow detectado!')  # Agora lanca excecao

# Ou converter pra Python int quando precisar de seguranca
safe_result = int(a) + 1  # Usa int nativo, sem overflow

Se voce trabalha com data science ou machine learning, presta atencao nisso. NumPy por padrao nao avisa sobre overflow. Voce vai achar que ta calculando metricas corretas, mas um unico overflow silencioso pode corromper todo o pipeline de dados. Use np.errstate(over='raise') nos pontos criticos.

TypeScript e C: aqui voce e responsavel

TypeScript compila pra JavaScript, entao herda todos os problemas do JS com numeros. O tipo number do TS e o mesmo IEEE 754 double do JS. Nao tem int nativo. Mas TypeScript te da uma vantagem: voce pode criar tipos que te forcam a pensar sobre overflow.

typescript
// Tipo branded para IDs seguros
type SafeId = bigint & { readonly __brand: 'SafeId' };

function createSafeId(value: number | string): SafeId {
  const id = BigInt(value);
  if (id < 0n) throw new Error('ID nao pode ser negativo');
  return id as SafeId;
}

// Funcao utilitaria pra operacoes financeiras
function safeAdd(a: bigint, b: bigint, maxValue: bigint): bigint {
  const result = a + b;
  if (result > maxValue) {
    throw new RangeError(
      `Overflow detectado: ${a} + ${b} = ${result} excede ${maxValue}`
    );
  }
  return result;
}

// Uso pratico: calculos financeiros em centavos
const preco = createSafeId('99999999999999'); // R$ 999.999.999.999,99 em centavos
const desconto = createSafeId('500');
const total = safeAdd(preco, desconto, BigInt('99999999999999999'));
console.log(`Total: ${total}`); // Seguro!

Ja em C e C++, overflow de inteiro com sinal e undefined behavior — o compilador pode fazer literalmente qualquer coisa. Incluindo otimizar fora o seu check de overflow se ele achar que 'nao deveria acontecer'. Nao e piada.

javascript
// Exemplo conceitual em C (mostrando em JS pra contexto)
// Em C, isso e undefined behavior:
// int x = INT_MAX; // 2147483647
// x = x + 1;       // Undefined behavior! Compilador pode remover checks

// O compilador GCC pode otimizar isso:
// if (x + 1 > x) {  // <- GCC pode remover esse check!
//   // "inteiro com sinal nunca da overflow", pensa o compilador
//   handleOverflow();
// }

// Solucao em C: usar tipos unsigned ou builtins
// __builtin_add_overflow(a, b, &result) // GCC/Clang
// ou usar unsigned int (overflow bem definido: wraps around)

Se voce programa em Rust, tem sorte: o compilador checa overflow em modo debug e faz wrap em release. Voce pode usar checked_add(), saturating_add() ou wrapping_add() pra ter controle explicito. Outras linguagens como Swift tambem lancam erro em overflow por padrao.

Auditoria de overflow no seu projeto

Beleza, agora voce sabe o que e overflow e como cada linguagem lida com ele. Mas como achar esses bugs no codigo que ja ta rodando? Aqui vai um checklist pratico.

Auditoria de overflow — passo a passo

  • Mapear todos os campos numericos do banco de dados e seus tipos (INT, BIGINT, etc.)
  • Verificar se IDs auto-incrementais podem estourar o limite do tipo usado
  • Buscar operacoes aritmeticas com Number em JS/TS que envolvam valores grandes
  • Checar se calculos financeiros usam BigInt ou Decimal, nunca float
  • Verificar se NumPy arrays usam dtype adequado (int64 vs int32) em pipelines de dados
  • Testar endpoints da API com valores no limite de cada tipo (MAX_SAFE_INTEGER, INT_MAX, etc.)
  • Adicionar validacao de range nos inputs do usuario antes de fazer calculos
  • Configurar linter rules pra detectar comparacoes de igualdade com numeros grandes

BigInt (JS/TS)

+ Prós

  • • Precisao arbitraria, sem limite de tamanho
  • • Nativo no JS moderno (ES2020+)
  • • Perfeito pra IDs, timestamps e financeiro

− Contras

  • • Nao mistura com Number em operacoes
  • • Nao serializa em JSON nativamente
  • • Nao funciona com Math.max, Math.min, etc.
  • • Performance menor que Number pra valores pequenos

int nativo Python

+ Prós

  • • Precisao arbitraria automatica
  • • Nenhuma configuracao necessaria
  • • Funciona com todas as operacoes nativamente

− Contras

  • • Mais lento que int fixo em operacoes pesadas
  • • NumPy nao usa int nativo por padrao
  • • Consumo de memoria cresce com o tamanho do numero

Tipos fixos (C/Rust/NumPy)

+ Prós

  • • Performance maxima
  • • Previsivel em termos de memoria
  • • Rust: checked_add detecta overflow em runtime

− Contras

  • • Overflow silencioso em C (undefined behavior)
  • • NumPy: overflow silencioso por padrao
  • • Dev precisa gerenciar limites manualmente

A regra geral e simples: se o numero pode crescer indefinidamente (IDs, contadores, valores financeiros), use tipos de precisao arbitraria. Se o numero tem range conhecido e previsivel (coordenadas de pixel, porcentagens, indices de array pequeno), tipos fixos sao mais eficientes. O problema e quando voce assume range fixo sem ter certeza — ai voce vira o proximo Ariane 5.

Escreva codigo que nao explode

No CrazyStack voce aprende a construir aplicacoes robustas com Node.js, React e TypeScript. Calculos financeiros, APIs que nao quebram com dados inesperados, testes que pegam edge cases. Tudo na pratica, com projetos reais.

Acesse crazystack.com.br e comece hoje.