Răspuns pe scurt
Când suma și n sunt int, suma / n face împărțire întreagă. Conversia rezultatului la double vine prea târziu. Convertește valoarea sumei la double înainte să o împarți la n, cu n pozitiv, pentru o medie care poate avea parte fracționară.
Media numerelor 7 și 8 este 7,5. În C++, dacă suma 15 și numărul valorilor 2 sunt int, suma / n produce însă 7. Salvarea într-un double vine după împărțire. Ca să păstrezi partea fracționară, convertește un operand înainte: static_cast<double>(suma) / n.
Urmărim acest calcul de la expresie până la afișare. Este un exemplu pentru primele lecții de C++ din liceu, când lucrezi cu tipuri numerice și medii.
Ce primește variabila medie?
int suma = 15;
int n = 2;
double medie = suma / n;
În dreapta semnului egal, suma și n sunt int. Împărțirea dă întregul 7. Acest 7 este apoi convertit la double și păstrat în medie. Tipul variabilei din stânga nu schimbă tipurile folosite la calculul din dreapta.
Proiectul standardului C++ precizează că împărțirea între întregi elimină partea fracționară. Nu rotunjește la cel mai apropiat întreg. Și -15 / 2 dă -7: trunchierea se face spre zero.
Două împărțiri, în același program
#include <iostream>
int main() {
int suma = 15;
int n = 2;
double prima = suma / n;
double a_doua = static_cast<double>(suma) / n;
std::cout << prima << '\n';
std::cout << a_doua << '\n';
}
Programul afișează 7 pe primul rând și 7.5 pe al doilea. În cod și la această afișare, separatorul zecimal este punctul; în explicațiile în română folosim virgula.
La al doilea calcul, static_cast<double>(suma) produce valoarea 15 de tip double. Variabila suma rămâne int, cu valoarea 15. Documentația Microsoft despre static_cast descrie această conversie explicită.
La împărțire, n este convertit și el la double, după regulile conversiilor aritmetice. Calculezi 15,0 / 2,0 și obții 7,5.
Paranteza arată ce convertești
Compară cele două forme cu static_cast. Când între paranteze se află întreaga împărțire, conversia vine prea târziu pentru a păstra partea fracționară.
| Expresia, cu suma = 15 și n = 2 | Rezultatul |
|---|---|
suma / n | 7, de tip int |
static_cast<double>(suma / n) | 7, de tip double |
static_cast<double>(suma) / n | 7,5, de tip double |
suma / 2.0 | 7,5, de tip double |
Ultimul rând funcționează pentru media a două valori fiindcă 2.0 are tipul double. Când numărul valorilor variază, păstrează n și folosește conversia din rândul al treilea.
De ce suma 16 ascunde greșeala?
Schimbă în program suma din 15 în 16. Ambele rânduri afișează 8. Împărțirea este exactă, așa că prima variantă pare corectă.
La o temă despre medii, testează și o sumă care nu se împarte exact la numărul valorilor. În programul nostru, n este fixat la 2. Dacă îl citești într-o altă rezolvare, verifică să fie pozitiv: nu poți calcula media unui grup fără valori împărțind la zero.
Împărțirea întreagă are, la rândul ei, un rost. Când vrei să elimini ultima cifră a unui număr natural, câtul întreg este tocmai rezultatul cerut.
Încearcă 19 înainte să rulezi
Pune suma = 19 și n = 2. Scrie pe hârtie cele două valori afișate, apoi explică de ce diferă. Poți folosi aceeași verificare fără rezolvarea în față și la alte expresii.
Pentru aceste date, primul rând afișează 9, iar al doilea 9.5. Dacă ai prevăzut 9.5 în ambele locuri, întoarce-te la tipurile celor două valori aflate lângă operatorul /.