«E no Rust, posso simplesmente escrever a ** b?» — Você pergunta e… erra
\n\nSe você veio do Python para o Rust, o primeiro choque é a ausência do operador **. O segundo choque é que o compilador não perdoa liberdades com tipos. O terceiro (agradável) é que o Rust oferece todo um arsenal de ferramentas para exponenciação, cada uma otimizada para uma tarefa específica.
Em 2025, quando o Rust está ativamente substituindo o C++ em sistemas de alta carga e desenvolvimento embarcado, a pergunta «How to raise a number to a power?» (que acumulou milhares de visualizações no Stack Overflow) tornou-se ainda mais relevante. Vamos entender de uma vez por todas: como elevar números à potência de forma correta, rápida e segura em Rust.
\n\nPor que o Rust não tem o operador **?
\n\nRust é uma linguagem de sistema. Ela não permite sobrecarga de operadores «em tempo real» (embora existam traits std::ops, mas não há para exponenciação). Em vez disso, os desenvolvedores propuseram métodos-função, que indicam explicitamente o tipo de operação. Isso elimina confusão entre exponenciação inteira e aritmética de ponto flutuante.
Regra fundamental: escolha o método de acordo com o tipo de dado. Não tente elevar i32 à potência f64 — o compilador não entenderá, e se entender (através de conversão), você corre o risco de perder desempenho ou precisão.
Método pow() — o rei dos números inteiros
\n\nA forma mais popular para i32, u64 e outros tipos inteiros:
fn main() {\n let base: i32 = 5;\n let exponent: u32 = 3;\n let result = base.pow(exponent);\n println!("5^3 = {}", result); // 125\n}\n\nObserve: exponent deve ser sempre u32 (sem sinal). Isso é lógico — a potência não pode ser negativa para números inteiros (caso contrário, você obteria uma fração).
Quando usar: sempre para cálculos com inteiros. Funciona rapidamente, sem alocações, no nível de instruções de máquina.
\n\nE se a potência for negativa?
\nPara números inteiros — de jeito nenhum. Rust não suporta potências negativas para tipos inteiros, porque o resultado seria fracionário. Se você precisa de 2^-3 — mude para números de ponto flutuante.
powi() — a escolha ideal para f64 e f32
\n\nEste método aceita um expoente inteiro (tipo i32), mas trabalha com números de ponto flutuante:
fn main() {\n let base: f64 = 2.0;\n let result = base.powi(-3);\n println!("2.0^-3 = {}", result); // 0.125\n\n // Também funciona com potência positiva\n let result2 = base.powi(10);\n println!("2.0^10 = {}", result2); // 1024.0\n}\n\nDestaque de 2025: powi() é otimizado para expoentes inteiros. Ele usa o algoritmo de exponenciação rápida (exponentiation by squaring). Se seu expoente é uma constante ou número inteiro, esta é a forma mais rápida para f64/f32.
powf() — quando a potência também é uma fração
\n\nSe tanto a base quanto o expoente são números de ponto flutuante, use powf():
fn main() {\n let base: f64 = 9.0;\n let exponent: f64 = 0.5;\n let result = base.powf(exponent);\n println!("9.0^0.5 = {}", result); // 3.0 (raiz quadrada)\n\n // Caso complexo\n let base2 = 2.0_f64;\n let exp2 = 3.14_f64;\n println!("2.0^3.14 = {}", base2.powf(exp2)); // ~8.815\n}\n\nImportante: powf() usa uma biblioteca matemática lenta, mas precisa (geralmente libm ou instrução de hardware). Para gráficos ou jogos, onde a velocidade é crucial, considere powi().
Crate num — o soldado universal
\n\nEm 2025, o ecossistema Rust oferece o crate num (e num-