De ce contează?
Ai 13 lei și vrei să-i dai doar în monede de 2 lei și de 1 leu. Iei cât mai multe monede de 2 (șase monede = 12 lei) și-ți rămâne 1 leu. Conversia unui număr într-o altă bază e exact acest joc de „grupare repetată": împarți mereu la bază și notezi ce-ți rămâne.
Două drumuri, două metode
Conversiile merg în ambele sensuri, dar folosesc procedee diferite:
- dintr-o bază oarecare → baza 10: înmulțești fiecare cifră cu valoarea ei de loc și aduni (schema lui Horner, din lecția anterioară).
- din baza 10 → o altă bază: faci împărțiri repetate la bază și aduni resturile.
Cheia e să nu le amesteci: spre baza 10 mergi prin valori de loc, dinspre baza 10 mergi prin împărțiri.
Din baza 10 într-o altă bază
Algoritmul: împarți numărul la bază, reții restul ca cifră, treci la cât, și repeți până ajungi la 0. Cifrele ies de la cea mai puțin semnificativă spre cea mai semnificativă, deci la final le citești invers.
Exemplu: 13 în baza 2.
13 : 2 = 6 rest 1
6 : 2 = 3 rest 0
3 : 2 = 1 rest 1
1 : 2 = 0 rest 1Resturile, în ordinea apariției, sunt 1, 0, 1, 1. Citite invers dau rezultatul:
| cifra | 1 | 1 | 0 | 1 |
| valoare loc | 8 | 4 | 2 | 1 |
De ce ordinea inversă? Prima împărțire scoate restul împărțirii la b, adică cifra unităților — poziția cea mai din dreapta. Ultima împărțire dă cifra cea mai din stânga. Deci ordinea găsirii e exact pe dos față de ordinea scrierii.
Implementare C++ — baza 10 → baza b
#include <iostream>
using namespace std;
int main() {
int n = 13, b = 2;
int cifre[40], k = 0;
while (n > 0) {
cifre[k++] = n % b; // restul = cifra curenta
n /= b; // catul = ce ramane de convertit
}
// afisam in ordine inversa fata de cum le-am gasit
for (int i = k - 1; i >= 0; i--) cout << cifre[i];
cout << "\n"; // 1101
return 0;
}Implementare C++ — baza b → baza 10
Aici aplici Horner pe cifrele citite de la stânga:
#include <iostream>
using namespace std;
int main() {
int cifre[] = {1, 1, 0, 1}; // 1101 in baza 2
int n = 4, b = 2;
int valoare = 0;
for (int i = 0; i < n; i++) {
valoare = valoare * b + cifre[i];
}
cout << valoare << "\n"; // 13
return 0;
}Complexitate
Ambele conversii costă O(k), unde k ≈ log_b n este numărul de cifre al rezultatului. Fiecare împărțire scade numărul de b ori, deci ajungi la 0 după aproximativ log_b n pași.
Vizualizare
Urmărește cum fiecare împărțire la bază scoate o cifră (restul) și micșorează numărul, până ajunge la 0 — iar cifrele citite invers formează rezultatul în noua bază:
Greșeala 1 — citești resturile în ordinea apariției: dacă afișezi 1,0,1,1 cum au ieșit, obții 1011 (= 11), nu 1101 (= 13). Resturile se citesc invers.
Greșeala 2 — confunzi cele două sensuri: încerci împărțiri repetate ca să mergi spre baza 10, sau Horner ca să mergi dinspre baza 10. Reține: împărțiri = ieși din baza 10; valori de loc = intri în baza 10.
Greșeala 3 — nu tratezi n = 0: bucla while (n > 0) nu rulează deloc pentru 0 și nu afișează nimic. Tratează separat cazul zero, afișând cifra 0.
Greșeala 4 — uiți literele peste baza 10: dacă restul e ≥ 10 (în baza 16), nu-l afișa ca număr; transformă-l în literă (10 → A, 11 → B, …).
Recapitulare
- Din baza 10 într-o altă bază: împărțiri repetate la bază; resturile sunt cifrele, citite în ordine inversă.
- Dintr-o bază oarecare în baza 10: schema lui Horner pe cifre, de la stânga la dreapta.
- Ambele metode rulează în O(log_b n); atenție la cazul
n = 0și la literele A–F când baza depășește 10.