Da un punto di vista matematico, preso un numero intero n, la scrittura n \div 2 equivale a n \times 0.5. Tuttavia, in C++ (come in numerosi altri linguaggi di programmazione) le due scritture non sono necessariamente equivalenti, da un punto di vista di codice compilato – ovvero quello che viene eseguito dal computer.
Leggendo il codice di esempio, troviamo che la riga interessata dal bug è
long long int res = abs(a) * 0.5;
e analizzando ulteriormente il codice possiamo trovare la definizione della variabile a
come
long long int a = 0;
Avendo questi dati, possiamo semplificare l’operazione, riassumendola come: long long int * 0.5
. In breve, stiamo moltiplicando un long long
per un float
. Per questo motivo, il compiler ha bisogno di fare un casting da long long
a un numero a virgola mobile.
Nell’operazione long long int / 2
, invece, stiamo dividendo un long long int
per un int
. In C++, la divisione tra due interi è possibile senza effettuare casting di alcun tipo – l’operatore /
è infatti associato all’operazione di divisione intera quando si lavora con due interi.
Operando con numeri molto grandi, è possibile che alcuni risultati non coincidano. Basta provare, anche su un IDE online, a lavorare su numeri come 2^{61} (il numero usato nell’esempio qui sotto).
Programma di esempio
#include <iostream>
using namespace std;
long long int moltiplicazione(long long int num)
{
long long int res = num * 0.5;
return res;
}
long long int divisione(long long int num)
{
long long int res = num / 2;
return res;
}
int main()
{
cout << " n * 0.5 | n / 2 \n-------------------|-------------------\n";
long long int n = 1LL << 62LL; // numero pari molto grande
cout << moltiplicazione(n) << '|' << divisione(n) << '\n';
n = n - 1; // numero molto grande ma dispari
cout << moltiplicazione(n) << '|' << divisione(n) << '\n';
return 0;
}
È possibile vedere le differenze tra le due funzioni in un explorer di codice compilato, come GodBolt – puoi vedere qui la differenza tra le due funzioni usate.
Spero di aver chiarito il tuo dubbio, se hai altre domande sentiti libero di chiedere chiarimenti, anche se è meglio aprire un nuovo thread – questo è stato chiuso 4 anni fa! – in modo da avere più visibilità.
Buona giornata!