Implizite Konvertierung von Double in int in mingw32

Implizite Konvertierung von Double in int in mingw32


Ich kann das Verhalten des folgenden Programms (kompiliert mit gcc auf mingw 32 Bit) nicht erklären. Ich bin mir des möglichen Genauigkeitsverlusts bei der impliziten Konvertierung von double nach int bewusst, aber ich würde erwarten, dass die beiden Fälle dieselbe Ausgabe liefern, da sie genau dieselben Operationen ausführen. Warum sind die beiden Ausgaben unterschiedlich?


#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

Antworten:


Mit pow(100, 0) pow(100, 1) und pow(100, 2) der Compiler ersetzt die Funktionsaufrufe durch Konstanten (1, 100, 10000 ), aber mit pow(100, i) es muss die Funktion tatsächlich zur Laufzeit aufrufen (wegen der Variable i als Argument übergeben wird), was zu zwei Ergebnissen von pow führt in der Form 0.99999999 und 99.999999 statt 1 und 100 (oder irgendwelche 2 der 3). Beim Abschneiden auf int nach der Multiplikation "verlieren" Sie zwei Einheiten.


Dies ist ein weiteres Beispiel dafür, warum in int konvertiert werden sollte ab double ist einfach rein böse :Es ist sehr schwer, subtile Fehler in Ihrem Programm zu finden (keine Compiler-Fehler).


Übrigens bin ich überrascht, dass der Compiler mit O2 hat die Schleife nicht entrollt, die Konstanten weitergegeben und dieselbe Optimierung erreicht (Ersetzen des Funktionsaufrufs durch konstante Ergebnisse).


Btw2 Streichen Sie das, ich bin überrascht, dass der Compiler nicht einfach Ihren gesamten Code durch nur zwei Aufrufe von printf ersetzt hat .