web-dev-qa-db-fra.com

Différence entre sqrt et sqrtf

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?

13
dato datuashvili

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().

16
In silico

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é. 

3
James Kanze

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.

3
Etienne de Martel

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 doubles) et sqrtf pour floats. 

2
Matteo Italia

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.

0
ceilingcat