« Peut-on simplement écrire a ** b en Rust ? » — Demandez-vous et… vous vous tromperez
\n\nSi vous venez du Python vers Rust, le premier choc est l'absence de l'opérateur **. Le deuxième choc est que le compilateur ne pardonne pas les libertés avec les types. Le troisième (agréable) est que Rust propose tout un arsenal d'outils pour l'exponentiation, chacun adapté à une tâche spécifique.
En 2025, alors que Rust remplace activement le C++ dans les systèmes à forte charge et le développement embarqué, la question « How to raise a number to a power? » (qui a recueilli des milliers de vues sur Stack Overflow) est devenue encore plus pertinente. Penchons-nous une fois pour toutes sur la manière correcte, rapide et sécurisée d'élever des nombres à une puissance en Rust.
\n\nPourquoi n'y a-t-il pas d'opérateur ** en Rust ?
\n\nRust est un langage système. Il ne permet pas de surcharger les opérateurs « à la volée » (bien que les traits std::ops existent, ils ne couvrent pas l'exponentiation). À la place, les développeurs ont proposé des méthodes-fonctions qui indiquent explicitement le type d'opération. Cela évite toute confusion entre l'exponentiation entière et l'arithmétique à virgule flottante.
Règle clé : choisissez la méthode en fonction du type de données. N'essayez pas d'élever un i32 à une puissance f64 — le compilateur ne vous comprendra pas, et s'il vous comprend (via une conversion), vous risquez de perdre en performance ou en précision.
La méthode pow() — la reine des entiers
\n\nLa méthode la plus populaire pour i32, u64 et autres types entiers :
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\nNotez que exponent doit toujours être de type u32 (non signé). C'est logique — la puissance ne peut pas être négative pour les entiers (sinon vous obtiendriez une fraction).
Quand l'utiliser : toujours pour les calculs entiers. Fonctionne rapidement, sans allocation, au niveau des instructions machine.
\n\nEt si la puissance est négative ?
\nPour les entiers — impossible. Rust ne prend pas en charge les puissances négatives pour les types entiers, car le résultat serait fractionnaire. Si vous avez besoin de 2^-3 — passez aux nombres à virgule flottante.
powi() — le choix idéal pour f64 et f32
\n\nCette méthode accepte un exposant entier (type i32), mais fonctionne avec des nombres à virgule flottante :
fn main() {\n let base: f64 = 2.0;\n let result = base.powi(-3);\n println!("2.0^-3 = {}", result); // 0.125\n\n // On peut aussi utiliser une puissance positive\n let result2 = base.powi(10);\n println!("2.0^10 = {}", result2); // 1024.0\n}\n\nAstuce 2025 : powi() est optimisé pour les exposants entiers. Il utilise l'algorithme d'exponentiation rapide (exponentiation by squaring). Si votre exposant est une constante ou un entier, c'est la méthode la plus rapide pour f64/f32.
powf() — quand la puissance est aussi une fraction
\n\nSi la base et l'exposant sont des nombres à virgule flottante, utilisez 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 (racine carrée)\n\n // Cas complexe\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\nImportant : powf() utilise une bibliothèque mathématique lente mais précise (généralement libm ou une instruction matérielle). Pour les graphismes ou les jeux où la vitesse est cruciale, envisagez powi().
La crate num — le soldat universel
\n\nEn 2025, l'écosystème Rust propose la crate num (et num-