Divisores de um número natural
Achei os divisores de um número de três formas diferentes antes de perceber que a segunda era a que eu ia usar o resto da vida. A primeira é a mais óbvia: testar se 1 divide, depois 2, depois 3, até chegar no número em si. Funciona. Pare de brincar. Para números pequenos você nem percebe o custo. Começa a perceber quando o número tem quatro dígitos ou mais. O que a maioria das pessoas não entende de cara é que os divisores vêm em pares. Se d é divisor de n, então n/d também é. Isso muda completamente a estratégia. Você para de testar até n e testa até a raiz quadrada. Todo divisor menor que sqrt(n) tem um par correspondente maior que sqrt(n). Você economiza exatamente metade dos testes, mas na prática é mais que isso porque já corta a complexidade de O(n) para O(n).
divisores de um numero natural
Vejo um exemplo prático. Quer os divisores de 36. Raiz quadrada é 6. Testa 1 — funciona, par é 36. Testa 2 — funciona, par é 18. Testa 3 — funciona, par é 12. Testa 4 — funciona, par é 9. Testa 5 — não divide. Testa 6 — funciona, mas o par é 6 mesmo, então anota só uma vez. Divisores: 1, 2, 3, 4, 6, 9, 12, 18, 36. nove divisores. Pronto. Agora vê o problema que eu tive na prática. Trabalhava com um número na casa dos milhões, gerando divisores para validar uma entrada de sistema. Achei que o método de teste até a raiz quadrada ia dar conta. Deu, mas demorou uns 40 segundos em uma máquina padrão. O usuário ficou olhando. Não era aceitável. A virada foi fatorar o número em primos primeiro e gerar os divisores a partir da fatoração, em vez de testar um por um. A diferença foi de 40 segundos para menos de meio segundo.
O método por fatoração funciona assim. Você decompoe o número em primos. Digamos que n = p1^a1 * p2^a2 * ... * pk^ak. O número de divisores é (a1+1)(a2+1)...(ak+1). E os divisores propriamente ditos são todas as combinações possíveis desses fatores primos com expoentes de 0 até o valor original. Para 60, que é 2^2 * 3^1 * 5^1, os divisores são gerados combinando 2^0, 2^1, 2^2 com 3^0, 3^1 e 5^0, 5^1. O resultado é 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60. Doze divisores. A fórmula (2+1)(1+1)(1+1) = 12 bate certo. Uma coisa que pouca gente explica e que vale a pena saber: números altamente compostos são os que têm mais divisores relativamente ao seu tamanho. O 360, por exemplo, tem 24 divisores. É um número pequeno e tem mais divisores que quase qualquer outro abaixo dele. Se você tá otimizando algo que depende de quantos divisores um número tem, esses são os alvos naturais.
A limitação real do método de fatoração é que fatorar números grandes em primos é um problema computacionalmente difícil. Não existe algoritmo eficiente conhecido para fatoração de números com dezenas de dígitos. Criptografia RSA depende exatamente disso. Se você tá lidando com números pequenos e médios, fatoração trial division ou Pollard's rho resolvem rápido. Se o número tem mais de 20 dígitos, o jogo muda completamente e você precisa de métodos como quadrática sieve ou elliptic curve method, que são outra conversa. Outro detalhe prático: números primos só têm dois divisores, 1 e eles mesmos. Se durante o teste até sqrt(n) você não achar nenhum divisor, o número é primo. Isso é útil porque às vezes o objetivo não é listar todos os divisores, só verificar se o número é primo ou não. Nesse caso, o teste de primalidade é mais rápido que gerar a lista completa.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Se você quiser um código simples em Python pra gerar divisores pelo método da raiz quadrada: def divisores(n):
divs = []
for i in range(1, int(n0.5) + 1):
if n % i == 0:
divs.append(i)
if i != n // i:
divs.append(n // i)
return sorted(divs)
Esse código retorna todos os divisores ordenados. Pra 36, retorna [1, 2, 3, 4, 6, 9, 12, 18, 36]. Função simples, funciona bem pra números até algumas centenas de milhares. Depois disso, migra pra fatoração em primos. Um erro comum que eu vejo todo dia: alguém testa divisibilidade só por 2, 3 e 5 e acha que já verificou tudo. Isso funciona pra criba de Eratóstenes em pequena escala, mas se o objetivo é encontrar todos os divisores, você precisa testar todos os candidatos até sqrt(n). Pulando passos só porque "provavelmente não vai ter divisor ali" é assim que você perde divisores e o resultado fica errado sem você perceber na hora.
Soma dos divisores é outro tópico que muitas vezes aparece junto. A função sigma_1(n) soma todos os divisores de n. Pra números perfeitos, a soma dos divisores próprios (excluindo o próprio número) é igual ao número. 6 é perfeito: 1+2+3 = 6. 28 também: 1+2+4+7+14 = 28. Números perfeitos são raros e a fórmula pra gerar os conhecidos depende de primos de Mersenne, o que é outra camada de complexidade que eu deixaria pra outra hora se o foco for só listar divisores. Se precisa de uma ferramenta pronta, existem calculadoras online de divisores e vários pacotes em linguagens como Python (sympy tem função divisors()), Java e C++. A escolha depende do tamanho do número e da velocidade que você precisa. Sympy é bom pra números de até alguns milhares de dígitos. Pra algo mais pesado, bibliotecas especializadas em teoria dos números como GMP ou PARI/GP são o caminho.
A regra prática que eu guardo: teste até sqrt(n) pra números pequenos e fatoração em primos pro resto. Se o número tiver mais de 15 dígitos, considere usar uma biblioteca especializada em vez de escrever do zero. E sempre valide o resultado somando os divisores ou checando a contagem pela fórmula dos expoentes mais um. Erros de implementação passam despercebidos com muita facilidade nesse tipo de código.