C: Ich habe unterschiedliche Ergebnisse mit pow (10,2) und pow (10, j), j = 2;

8

dieser druckt 100:

%Vor%

und dieser druckt 99:

%Vor%

warum?

    
Rimgaudas Tumėnas 01.10.2013, 22:06
quelle

3 Antworten

12

Was passiert, ist, dass Sie eine C-Implementierung haben, deren Standardbibliothek eine Implementierung von pow mit sehr geringer Qualität hat, die ungenaue Ergebnisse liefert, selbst wenn das genaue Ergebnis im Typ darstellbar ist ( double ). Der Aufruf von pow(10,2) scheint den Wert direkt unter 100.0 zu erzeugen, was, wenn er auf eine Ganzzahl gerundet wird, 99 ergibt. Der Grund, warum Sie dies nicht sehen, wenn die Argumente konstant sind, ist, dass der Compiler sich die Freiheit zur Optimierung genommen hat aus dem Aufruf all zusammen und ersetzen sie durch eine Konstante 100 bei compiletime.

Wenn Sie beabsichtigen, ganzzahlige Potenzen zu verwenden, verwenden Sie nicht die Funktion pow . Schreibe eine richtige ganzzahlige Potenzfunktion, oder wenn der Exponent bekannt ist, schreibe einfach die Multiplikation direkt aus.

    
R.. 01.10.2013, 23:08
quelle
2

Im ersten Fall vermute ich, dass der Compiler den Wert auf 10*10 optimiert hat, ohne tatsächlich pow aufzurufen (Compiler tun dies tatsächlich). Im zweiten Fall sieht es so aus, als ob Sie einen Gleitkomma-Rundungsfehler haben. Das Ergebnis ist fast 100, aber nicht ganz, und die implizite Umwandlung in int schneidet es ab.

Die Funktion pow funktioniert auf double , nicht auf int .

Im Allgemeinen (aber nicht immer), wenn Sie doubles in Integer konvertieren, rufen Sie round() auf. ZB:

%Vor%

Wenn Ihre C-Bibliothek dies nicht hat, können Sie emulieren:

%Vor%     
paddy 01.10.2013 22:19
quelle
0

pow gibt double zurück, und wenn das Ergebnis nicht genau 100 ist, aber etwas weniger, als es beim Konvertieren in eine int abgeschnitten wird, erhalten Sie das 99 Ergebnis, das Sie sehen. Es wäre interessant zu sehen, wie die Ergebnisse für eine double Variable und %f Format aussehen.

Der Grund, warum Sie es nicht sehen werden, wenn Sie Literale verwenden, ist das konstante Falten , das den Aufruf verursachen wird pow wird optimiert und durch eine Konstante ersetzt. Wir können die Version sehen, die Konstanten verwendet, wenn wir die Assembly erzeugen, kein Aufruf von pow gemacht wird, sondern nur das Endergebnis 100 ( siehe leben ):

%Vor%

während die Version der zweiten Version tatsächlich pow aufruft ( siehe live ):

%Vor%     
Shafik Yaghmour 01.10.2013 22:24
quelle

Tags und Links