ALGO25 / BLOG

Puteri în C++: de ce ^ nu este pow

Separă puterea matematică, operatorul XOR și funcția pow. Alege un calcul întreg când rezultatul trebuie să fie exact și verifică limitele intermediare.

În C++, expresia 2^3 nu înseamnă doi la puterea a treia. Operatorul ^ este XOR pe biți, adică pune 1 în pozițiile unde biții operanzilor diferă. Pentru 2, scris binar 10, și 3, scris 11, rezultatul este 01, adică 1.

Puterea matematică repetă înmulțirea

Doi la puterea a treia înseamnă 2·2·2=8. Pentru un exponent natural mic și un rezultat întreg exact, poți porni de la 1 și înmulți repetat cu baza. Exponentul zero produce 1 conform convenției uzuale pentru o bază nenulă.

Limitele contează: fiecare produs intermediar trebuie să încapă în tipul folosit. Faptul că baza și exponentul încap într-un int nu spune nimic despre putere. Pentru cerințe modulo, reducerea la fiecare pas păstrează valori mai mici, dar trebuie verificată și înmulțirea dinaintea reducerii.

Ce rol are pow

Funcția std::pow, din antetul <cmath>, calculează puteri în aritmetică în virgulă mobilă pentru utilizările numerice obișnuite. Ea este potrivită pentru probleme care acceptă rezultate reale și erori de rotunjire, în limitele domeniului funcției.

Conversia rezultatului la un tip întreg nu transformă operația într-o putere întreagă exactă. Dacă valoarea calculată diferă puțin de întregul dorit, conversia poate elimina partea fracționară într-un mod nepotrivit. Nu este nevoie ca fiecare apel pow să greșească pentru ca această dependență de aproximare să fie o alegere slabă într-o cerință exactă.

În C++, 2^3 este o operație XOR pe biți: 10 XOR 11 produce 01, adică 1. Puterea matematică 2 la 3 este 8.În C++, 2^3 este o operație XOR pe biți: 10 XOR 11 produce 01, adică 1. Puterea matematică 2 la 3 este 8.Mărește schema ↗

Pentru exponenți mari, redu numărul înmulțirilor

Ridicarea rapidă la putere folosește descompunerea exponentului: o putere pară se poate obține prin pătratul unei puteri cu exponent înjumătățit. Astfel numărul înmulțirilor crește logaritmic în exponent, în loc să fie proporțional cu el.

Această optimizare schimbă timpul, nu capacitatea tipului numeric. O putere prea mare rămâne prea mare. Separă alegerea algoritmului de alegerea reprezentării rezultatului.

Verificare de înțelegere

Prezice 2^3, puterea matematică 2³ și puterea 3²: rezultatele sunt 1,8,9. Apoi testează exponenții 0 și 1 în algoritmul ales. Dacă enunțul permite baza zero și exponentul zero, stabilește convenția cerută înainte de implementare.

Continuă cu operațiile pe biți, puterea rapidă și funcțiile matematice.

Întrebări frecvente

Operatorul ^ calculează o putere în C++?

Nu. ^ este XOR pe biți, care compară biții operanzilor. Expresia 2^3 produce 1, nu 8. Pentru puteri trebuie folosit un calcul dedicat.

Este pow soluția potrivită pentru orice putere întreagă exactă?

Nu automat. Calculele în virgulă mobilă pot introduce rotunjiri. Pentru un exponent natural și rezultat întreg exact, folosește înmulțiri controlate și verifică limitele valorilor intermediare.

Cum calculez eficient o putere cu exponent mare?

Exponentierea rapidă reduce numărul înmulțirilor la O(log e), unde e este exponentul. Ea nu elimină riscul de overflow; tipul și eventualul calcul modulo trebuie alese după problemă.