Conversione implicita doppia in int in mingw32

Conversione implicita doppia in int in mingw32


Non riesco a spiegare il comportamento del seguente programma (compilato con gcc su mingw 32 bit). Sono consapevole della possibile perdita di precisione durante la conversione implicita da double a int, ma mi aspetto che i due casi diano lo stesso output poiché sta eseguendo esattamente le stesse operazioni. Perché le due uscite sono diverse?


#include <stdio.h>
#include <math.h>
int main()
{
int table[3] = {2, 3, 4};
int i, N;
N = 0;
N += table[0] * pow(100, 0);
N += table[1] * pow(100, 1);
N += table[2] * pow(100, 2);
printf("%d\n", N);
N = 0;
for(i = 0; i < 3; i++)
N += table[i] * pow(100, i);
printf("%d\n", N);
return 0;
}
//output:
40302
40300

Risposte:


Con pow(100, 0) pow(100, 1) e pow(100, 2) il compilatore sostituisce le chiamate di funzione con costanti (1, 100, 10000 ), ma con pow(100, i) deve effettivamente chiamare la funzione in fase di esecuzione (a causa della variabile i passato come argomento), risultando con due risultati di pow nel modulo 0.99999999 e 99.999999 invece di 1 e 100 (o qualsiasi 2 dei 3). Quando si tronca a int dopo la moltiplicazione si "perdono" due unità.


Questo è un altro esempio del perché la conversione a int da double è solo puro male :molto difficile trovare bug sottili nel tuo programma (non bug del compilatore).


A proposito, sono sorpreso che il compilatore con O2 non ha svolto il ciclo, non ha propagato le costanti e ha raggiunto la stessa ottimizzazione (sostituendo la chiamata di funzione con risultati costanti).


A proposito, sono sorpreso che il compilatore non abbia semplicemente sostituito tutto il codice con solo due chiamate a printf .