La BAC informatică, operatorii / și % apar peste tot: în itemii de evaluare a expresiilor de la Subiectul I, în algoritmii în pseudocod de la Subiectul II și în aproape orice problemă cu cifre sau divizibilitate de la Subiectul III. Sunt doi operatori simpli, dar au câteva reguli pe care trebuie să le știi exact, nu „cam așa”.
Împărțirea întreagă în C++: când / taie zecimalele
În C++, rezultatul lui / depinde de tipul operanzilor. Dacă ambii operanzi sunt întregi (int, long long, char etc.), împărțirea este întreagă: partea fracționară se pierde. Dacă măcar unul dintre operanzi este real (float, double), împărțirea este reală.
7 / 2are valoarea37.0 / 2are valoarea3.52 / 5are valoarea0(double)7 / 2are valoarea3.5, pentru că 7 e convertit la real înainte de împărțire
Ultimul caz e important. Dacă vrei media aritmetică a două numere întregi, double m = (a + b) / 2; este greșit: împărțirea se face întâi între întregi, iar abia rezultatul trunchiat se pune în m. Pentru a = 3 și b = 4 obții 3, nu 3.5. Corect este (a + b) / 2.0 sau (double)(a + b) / 2.
În pseudocodul de la BAC, împărțirea întreagă se scrie cu partea întreagă: [x/y]. Când traduci în C++ și variabilele sunt întregi, [x/y] devine pur și simplu x / y.
Restul împărțirii: operatorul %
a % b este restul împărțirii lui a la b. Funcționează doar pentru operanzi întregi: 7.5 % 2 nu se compilează. Câteva valori de reținut:
17 % 5 = 2, pentru că 17 = 3·5 + 24 % 9 = 4— dacă deîmpărțitul e mai mic decât împărțitorul, restul e chiar deîmpărțitul20 % 5 = 0— rest zero înseamnă divizibilitatea % 1 = 0pentru oricea
Relația care leagă cei doi operatori este valabilă întotdeauna (pentru b ≠ 0):
a == (a / b) * b + a % b
Împărțirea la zero, fie cu /, fie cu %, între întregi, este o eroare la execuție. Dacă un algoritm poate ajunge să împartă la o variabilă care devine 0, verifică întâi.
Ce se întâmplă cu numerele negative
În C++ (de la standardul C++11 încoace), împărțirea întreagă trunchiază spre zero, iar restul are semnul deîmpărțitului:
| Expresie | Valoare | Verificare |
|---|---|---|
-7 / 2 | -3 | -3,5 trunchiat spre zero |
-7 % 2 | -1 | (-3)·2 + (-1) = -7 |
7 / -2 | -3 | -3,5 trunchiat spre zero |
7 % -2 | 1 | (-3)·(-2) + 1 = 7 |
-7 % -2 | -1 | 3·(-2) + (-1) = -7 |
Consecința practică: testul x % 2 == 1 nu recunoaște numerele impare negative, pentru că -7 % 2 este -1. Dacă datele pot fi negative, scrie x % 2 != 0. Majoritatea problemelor de BAC lucrează cu numere naturale, dar e bine să știi capcana pentru grile.
Ultima cifră, primele cifre și eliminarea cifrelor
Pentru un număr natural n scris în baza 10:
n % 10este ultima cifră (cifra unităților)n / 10este numărul fără ultima cifrăn % 100este numărul format din ultimele două cifren / 10 % 10este cifra zecilorn % 10 == n / 10 % 10verifică dacă ultimele două cifre sunt egale
Pentru n = 4728: n % 10 = 8, n / 10 = 472, n % 100 = 28, n / 10 % 10 = 2, n / 100 = 47.
Prima cifră nu se obține dintr-o singură operație, pentru că nu știi câte cifre are numărul. O obții împărțind la 10 cât timp numărul are cel puțin două cifre:
while (n >= 10)
n = n / 10;
// acum n este prima cifră
Paritate și divizibilitate
Restul este instrumentul standard pentru orice întrebare de tipul „se împarte exact?”:
x % 2 == 0—xeste parx % k == 0—xeste divizibil cuk(saukeste divizor al luix)x % 3 == 0 && x % 5 == 0— divizibil cu 3 și cu 5, adică cu 15(a + b) % 2 == 0—așibau aceeași paritate
Un exemplu care combină ambii operatori: transformarea unei durate date în secunde în ore, minute și secunde.
#include <iostream>
using namespace std;
int main()
{
int s;
cin >> s; // de exemplu 3725
int ore = s / 3600;
int minute = s % 3600 / 60;
int secunde = s % 60;
cout << ore << " " << minute << " " << secunde;
return 0;
}
Pentru 3725 se afișează 1 2 5: 3725 / 3600 = 1, 3725 % 3600 = 125, 125 / 60 = 2, iar 3725 % 60 = 5.
Precedența: cum evaluezi o expresie la grile
*, / și % au aceeași prioritate și se evaluează de la stânga la dreapta. Toate trei au prioritate mai mare decât + și -. Iată două expresii tipice de la Subiectul I:
2023 / 10 % 10 * 3: 2023 / 10 = 202, apoi 202 % 10 = 2, apoi 2 * 3 = 617 % 5 * 2 + 17 / 5: 17 % 5 = 2, 2 * 2 = 4, 17 / 5 = 3, deci 4 + 3 = 7
Greșeala clasică este să faci întâi înmulțirea, ca la matematică „pentru că pare mai importantă”. Nu: la aceeași prioritate contează doar ordinea de la stânga la dreapta.
[n/10] și n%10 la fiecare pas. Calculul „din cap” al restului este cea mai frecventă sursă de greșeli la itemul a) de la Subiectul II.Exerciții rapide
- Ce valoare are
125 / 10 / 10 + 125 % 10? (Răspuns: 1 + 5 = 6.) - Ce valoare are
-17 / 5? Dar-17 % 5? (Răspuns: -3 și -2, pentru că (-3)·5 + (-2) = -17.) - Scrie o expresie care are valoarea 1 dacă și numai dacă numărul natural
nare cifra zecilor egală cu 0. (Răspuns:n / 10 % 10 == 0.)
De reținut
- ● Între doi întregi,
/face împărțire întreagă; pentru rezultat real, unul dintre operanzi trebuie să fie real. - ●
%funcționează doar cu întregi, iara == (a / b) * b + a % b. - ● La numere negative, C++ trunchiază spre zero, iar restul are semnul deîmpărțitului.
- ●
n % 10dă ultima cifră,n / 10o elimină,x % k == 0testează divizibilitatea. - ●
*,/,%au aceeași prioritate și se evaluează de la stânga la dreapta.