Je veux envisager de coder. D'abord c'est:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt(s) << endl;
return 0;
}
Cela m'a donné cette erreur:
>c:\users\datuashvili\documents\visual studio 2010\projects\training\training\training.cpp(9): error C2668: 'sqrt' : ambiguous call to overloaded function
1> c:\program files\Microsoft visual studio 10.0\vc\include\math.h(589): could be 'long double sqrt(long double)'
1> c:\program files\Microsoft visual studio 10.0\vc\include\math.h(541): or 'float sqrt(float)'
1> c:\program files\Microsoft visual studio 10.0\vc\include\math.h(127): or 'double sqrt(double)'
1> while trying to match the argument list '(int)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Si j'ajoute le type float entre crochets devant s, comme ceci:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt((float)s) << endl;
return 0;
}
J'ai eu comme je devinerais, 5
. Et une autre variante est qu'au lieu de sqrt
, si j'écris sqrtf
:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main(){
int s=25;
cout << sqrtf((float)s) << endl;
return 0;
}
J'ai aussi eu 5
.
Quelle est la différence entre eux? Cela signifie-t-il que sqrtf est identique à sqrt pour le type float?
Voici une page sur la documentation MSDN pour sqrt()
et sqrtf()
, qui explique la différence:
sqrt, sqrtf
Calcule la racine carrée.
double sqrt( double x ); float sqrt( float x ); // C++ only long double sqrt( long double x ); // C++ only float sqrtf( float x );
Paramètres
x: valeur à virgule flottante non négative
Remarques
C++ permet la surcharge, de sorte que les utilisateurs peuvent appeler des surcharges de sqrt qui prennent des types float ou long double. Dans un programme C, sqrt toujours Prend et retourne double.
Valeur de retour
La fonction sqrt renvoie la racine carrée de x. Si x Est négatif, sqrt renvoie un nombre indéterminé, par défaut.
Donc, la différence en C++ est que sqrt()
accepte soit une double
, une float
ou un long double
tant que sqrtf()
accepte uniquement une float
.
Comme le dit la documentation, la seule raison pour laquelle il existe deux versions est que C ne supportait pas la surcharge, il devait donc y avoir deux fonctions. C++ permet la surcharge, il existe donc trois versions différentes de sqrt()
prenant des arguments en virgule flottante de différentes tailles.
Ainsi, en C++, vos deux extraits de code font essentiellement la même chose. Sur C, cependant, il y aurait eu une conversion de float
en double
dans l'appel sqrt()
.
En C++, la fonction sqrt
est surchargée pour prendre soit un double
, un float
ou un long double
en argument. Lorsque vous passez une int
, tous les Trois peuvent être appelés, et le compilateur n'a aucun moyen de choisir un Plutôt que les autres. L'appel est donc ambigu. Si vous convertissez explicitement La int
en float
, bien sûr, l’un des trois correspond exactement, Qui le rend meilleur que les deux autres, ainsi il est appelé.
La fonction sqrtf
est de C; en C, il n'y a pas de surcharge; sqrt
est toujours sqrt(double)
, et sqrtf
prend un float
. Puisque cette fonction N'est pas surchargée, l'appel ne peut pas créer d'ambiguïté.
C ne supportait pas la surcharge de fonction. Cela signifie qu'il devait y avoir une fonction différente pour chaque type. Par conséquent, sqrt
pour double
et sqrtf
pour float
. Puisque double
était le type "préféré" pour les nombres à virgule flottante en C, la version "par défaut" était celle de double
. Les deux font partie de la bibliothèque standard C, dans math.h
.
En C++, la sqrt
surchargée (définie dans cmath
, dans l'espace de noms std
) doit être utilisée.
sqrtf
est un héritage de C.
En C++, nous avons une surcharge et la fonction sqrt
a des surcharges différentes pour les trois types à virgule flottante. En C, au lieu de cela, il n'y a pas de surcharge, donc les différentes versions de la fonction racine carrée doivent être distinguées avec le nom de la fonction; par conséquent, nous avons sqrt
(cela en C ne fonctionne que sur double
s) et sqrtf
pour float
s.
sqrtf()
est plus rapide que sqrt()
... mais vous payez un prix avec précision.
C:\Users\ceilingcat> type f.cc
#include<iostream>
#include<cmath>
int main(){
double f=0;
int i=0;
for( ; i <= 2000000000; f+=sqrt(i++) );
std::cout.precision( 20 );
std::cout<<f<<'\n';
}
C:\Users\ceilingcat> cl f.cc /Ox /Arch:AVX2 /fp:fast /Qfast_transcendentals
C:\Users\ceilingcat> time ./f.exe
59628479422355.53125
real 0m3.846s
user 0m0.000s
sys 0m0.015s
C:\Users\ceilingcat> type g.cc
#include<iostream>
#include<cmath>
int main(){
double f=0;
int i=0;
for( ; i <= 2000000000; f+=sqrtf(i++) );
std::cout.precision( 20 );
std::cout<<f<<'\n';
}
C:\Users\ceilingcat> cl g.cc /Ox /Arch:AVX2 /fp:fast /Qfast_transcendentals
C:\Users\ceilingcat> time ./g.exe
59628479422157.773438
real 0m2.104s
user 0m0.000s
sys 0m0.000s
N.B. J'ai utilisé des indicateurs de compilateur fous pour souligner la différence sur mon matériel. Sauf si vous savez vraiment ce que vous faites, vous devriez probablement utiliser des drapeaux plus conservateurs.