GCC C++ Pow-Genauigkeit

Lesezeit: 3 Minuten

Benutzer-Avatar
Michael Chen

Ich war also bei einem Computerwettbewerb und habe einen seltsamen Fehler bemerkt. pow(26,2) würde immer 675 und manchmal 674 zurückgeben? obwohl die richtige Antwort 676 ist. Diese Art von Fehlern treten auch bei pow (26,3), pow (26,4) usw. auf. Nach einigem Debuggen nach dem Wettbewerb glaube ich, dass die Antwort mit der Tatsache zu tun hat, dass int abrundet. Interessanterweise ist mir diese Art von Fehler noch nie aufgetreten. Auf dem Computer, den ich hatte, lief mingw unter Windows 8. Die GCC-Version war ziemlich neu, etwa 2-3 Monate alt, glaube ich. Aber ich fand heraus, dass diese Art von Fehler auf wundersame Weise verschwinden würde, wenn ich das o1/o2/o3-Optimierungs-Flag aktivieren würde. pow(26,2) würde immer 676 aka richtige Antwort erhalten Kann jemand erklären warum?

#include <cmath> 
#include <iostream> 

using namespace std; 
int main() { 
    cout<<pow(26,2)<<endl; 
    cout<<int(pow(26,2))<<endl; 
}

Ergebnisse mit Doubles sind seltsam.

double a=26; 
double b=2; 
cout<<int(pow(a,b))<<endl; #outputs 675 
cout<<int(pow(26.0,2.0))<<endl; # outputs 676 
cout<<int(pow(26*1.00,2*1.00))<<endl; # outputs 676

  • pow(26,2) wie in 26 * 26 = 676?

    – Alexei Levenkov

    8. Dezember 2012 um 6:01 Uhr

  • ja, pow wie in der Standard-Power-Funktion.

    – Michael Chen

    8. Dezember 2012 um 6:02 Uhr

  • Bitte überprüfen Sie den Code erneut und korrigieren Sie ihn mit den korrekten falschen Zahlen.

    – cxxl

    8. Dezember 2012 um 7:14 Uhr

  • Mögliches Duplikat von C: Ich habe unterschiedliche Ergebnisse mit pow(10,2) und pow(10,j), j=2;

    – phuklv

    9. April 2019 um 8:24 Uhr

  • Warum gibt der gcc-Compiler pow(10,2) als 99 und nicht als 100 aus?, Warum pow(10,5) = 9.999 in C++

    – phuklv

    9. April 2019 um 8:25 Uhr

Benutzer-Avatar
Lindydancer

Die Funktion pow arbeitet mit zwei Gleitkommawerten und kann einen zum anderen erhöhen. Dies erfolgt durch einen Annäherungsalgorithmus, da es erforderlich ist, Werte vom kleinsten bis zum größten verarbeiten zu können.

Da dies ein Näherungsalgorithmus ist, wird der Wert manchmal etwas falsch angezeigt. In den meisten Fällen ist dies in Ordnung. Wenn Sie jedoch an einem genauen Ergebnis interessiert sind, verwenden Sie es nicht.

Ich würde dringend davon abraten, es für ganze Zahlen zu verwenden. Und wenn der zweite Operand bekannt ist (in diesem Fall 2), ist es trivial, ihn durch Code zu ersetzen, der dies viel schneller macht und den richtigen Wert zurückgibt. Zum Beispiel:

template<typename T>
T square(T x)
{
  return x * x;
}

Um die eigentliche Frage zu beantworten: Einige Compiler können Aufrufe an ersetzen pow mit anderem Code, oder eliminieren Sie alles zusammen, wenn eines oder beide Argumente bekannt sind. Dies erklärt, warum Sie unterschiedliche Ergebnisse erhalten.

  • Gibt es einen bestimmten Grund, warum Sie empfehlen, ein Makro und keine Funktion zu verwenden?

    – NPE

    8. Dezember 2012 um 8:42 Uhr

  • Außerdem würde ich tauschen ist bekannt mit ist eine bekannte kleine ganze Zahl. Es nützt nicht viel, wenn es entweder groß oder gebrochen ist.

    – NPE

    8. Dezember 2012 um 8:43 Uhr

  • @NPE, ich habe ein Makro ausgewählt, da es typneutral ist und einfach zu tippen war :). Wenn Sie den Typ kennen, können Sie natürlich eine Funktion definieren, alternativ einen Satz überladener Funktionen oder sogar eine Vorlagenfunktion.

    – Lindydancer

    8. Dezember 2012 um 8:57 Uhr

  • Ich hätte die Antwort positiv bewertet, aber ich mag die Idee, dafür ein Makro zu verwenden, insbesondere in C++, nicht.

    – NPE

    8. Dezember 2012 um 8:59 Uhr

  • wie wäre es mit einer Vorlage. Beste aus beiden Welten.

    – rubenvb

    8. Dezember 2012 um 10:03 Uhr

1015870cookie-checkGCC C++ Pow-Genauigkeit

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy