O básico que todo mundo esquece
Um número inteiro é qualquer número da sequência ..., -3, -2, -1, 0, 1, 2, 3, ... Sem frações, sem decimais, sem ponto flutuante. É isso. A definição é simples demais para causar confusão, mas é na hora de colocar em prática que as coisas começam a dar errado. Eu trabalho com sistemas que processam milhares de transações por segundo, e já vi estourar porque alguém assumiu que um inteiro aguentava qualquer valor que entrasse. Um inteiro de 32 bits com sinal vai de -2.147.483.648 a 2.147.483.647. Se o dado que você está lidando passar disso, o número simplesmente vira negativo. Já vi relatórios financeiros com valores negativos por causa disso. O bug foi rastreado até uma coluna que deveria ser bigint e tinha sido declarada como int por preguiça.
o'que é um numero inteiro
No dia a dia, o conceito é direto. Você conta coisas discretas: unidades, pessoas, itens, segundos inteiros. Tudo que não se divide em partes fracionárias se encaixa ali. O conjunto dos inteiros é representado pelo símbolo Z, vind do alemão Zahlen (números). Isso é tudo que a matemática exige. Quando você entra no mundo da programação, a coisa muda. Aqui estão os detalhes que as pessoas ignoram.
A primeira armadilha é a divisão inteira. Em Python, 7 // 2 devolve 3. Em C e Java, 7 / 2 também devolve 3, porque a parte decimal é truncada. O resultado é diferente quando os números são negativos: em Python, -7 // 2 resulta em -4, porque o operador faz arredondamento para baixo (floor division). Em C99 e derivados, -7 / 2 resulta em -3, porque a linguage especifica truncamento para zero. Essa diferença existe desde os primórdios da computação e já causou bugs silenciosos em softwares de controle de voo e sistemas bancários. Se você está fazendo portabilidade de código entre linguagens, não assume que a divisão inteira se comporta da mesma forma. A segunda coisa que ninguém te avisa é sobre two's complement. Quase toda arquitetura moderna representa inteiros negativos usando esse formato. A consequência prática é que existe um número a mais de negativos do que de positivos. Em 32 bits, você tem -2.147.483.648 como limite inferior, mas só chega até 2.147.483.647 no positivo. O número -2.147.483.648 não tem um par positivo correspondente dentro do mesmo tipo. Isso significa que operações como abs(-2147483648) podem transbordar e produzir o próprio -2147483648. É um bug clássico que aparece em auditorias de segurança.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Se você precisa trabalhar com inteiros realmente grandes, como hashes de 128 bits ou chaves criptográficas, os tipos nativos da linguagem não vão servir. A solução mais comum é usar uma biblioteca como GMP (GNU Multiple Precision) em C, ou simplesmente mudar para uma linguagem que suporte big integers nativamente, como Python ou Go com o pacote math/big. Em Python, aliás, a precisão é ilimitada na prática — o único limite é a memória disponível. Eu usei isso recentemente para calcular combinações de números com mais de 500 dígitos. Um programa equivalente em C++ travaria em minutos por overflow, enquanto em Python rodou limpo. Outro ponto que vale mencionar: inteiros não assinados (unsigned). Eles dobram o limite superior porque não precisam reservar um bit para o sinal. Um uint32 vai até 4.294.967.295. Mas isso cria um comportamento estranho quando você subtrai um número maior de um menor. Em vez de retornar um negativo, o resultado "vira" para o outro lado do espectro. 0 - 1 em uint8 resulta em 255. Isso acontece com frequência em loops que decrementam até zero e depois continuam, gerando iterações infinitas difíceis de detectar.
Na minha experiência, o pior cenário é quando você mistura tipos diferentes na mesma operação. Se você faz uma subtração entre um inteiro assinado e um não assinado em C++, o compilador converte o assinado para não assinado antes de calcular. Se o resultado for negativo, ele simplesmente não cai num erro — ele produz um número enorme e silencia o problema. Já depurei isso durante três horas numa função que parecia correta no papel. O que recomendo na prática é ser explícito com os tipos desde o início. Use int64 ou long long quando houver qualquer chance de crescimento. Evite unsigned exceto quando você tem um motivo claro para isso, como otimização de memória em arrays grandes ou representação de bitmap. E sempre valide os limites dos dados antes de fazer operações aritméticas. Um check simples de range pode economizar horas de debugging.
Se você está começando agora e quer estudar mais, a documentação do C (C11, seção 6.2.5) tem uma descrição técnica precisa dos tipos inteiros e suas garantias. Para Python, a seção de Números Inteiros na documentação oficial cobre o comportamento de precisão arbitrária. E se o seu interesse é segurança, dê uma olhada nos advisories do CERT sobre integer overflow — tem casos reais de aplicações comprometidas por esse tipo de erro. Resumindo de forma útil: inteiro é um número sem casas decimais. Parece óbvio, mas a parte difícil é saber onde ele para de funcionar e o que acontece quando para. Nada disso é complicado de entender, só precisa ser observado.