2010-11-18 7 views
2

Pourquoi y a-t-il des erreurs ici?Problème de sqrt en C++

#include <iostream> 
#include <math.h> 
#include <vector> 
#include <ostream> 

using namespace std; 

struct Point { 
    int x,y; 
}; 

int distance (const Point& a,const Point& b){ 
    int k= sqrt(((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))); 
} 

int main(){ 
    return 0; 
} 

sortie Build:

1>------ Build started: Project: distance, Configuration: Debug Win32 ------ 
1> distance.cpp 
1>d:\...\distance.cpp(13): error C2668: 'sqrt' : ambiguous call to overloaded function 
1>   c:\...\vc\include\math.h(589): could be 'long double sqrt(long double)' 
1>   c:\...\vc\include\math.h(541): or  'float sqrt(float)' 
1>   c:\...\vc\include\math.h(127): or  'double sqrt(double)' 
1>   while trying to match the argument list '(const int)' 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Répondre

4

sqrt prend un double (apparemment différents doubles différents dans votre compilateur) - vous le transmettre un entier

juste faire sqrt ((double) ..

Ok - pour être plus précis, sqrt() doit prendre un nombre à virgule flottante - un flottant ou un double. Pour diverses raisons historiques, il est généralement capable de convertir entre différents types de virgule flottante. Le bit de votre CPU faisant le calcul de sqrt est probablement (en supposant que x86) fait le calcul en 80bits qui n'est ni un float ni un double/

+0

'sqrt' est surchargé pour être surchargé pour' float', 'long double' et' double' en C++. (Voir 26.5 [lib.c.math]) –

+0

... et 'float' n'est pas" un autre 'double'". – You

+1

@You - c'est juste un double qui a été au régime. –

0

Il y a trois méthodes sqrt: Une qui prend un long, une qui prend un float et celui qui prend une valeur double.

Essayez

int k= (int)sqrt((double)(((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y)))); 

pour indiquer au compilateur que vous souhaitez utiliser la double version, puis reconvertir en int.

4

cela devrait fonctionner

float k= sqrt((float)((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))); 

sqrt() ne prend pas int en tant que paramètre.

+1

Utilise le double de préférence pour flotter. Pourquoi donner de la précision et le FPU va probablement opérer sur un double de toute façon, puis rejeter la précision de la conversion en flotteur. –

4

Vous ne pouvez pas prendre le sqrt d'un nombre entier. Il doit être un nombre à virgule flottante.

Vous devez faire quelque chose comme ceci:

int k= (int)sqrt((double)((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))); 

Le (double) convertit le int en double ant la (int) la convertit en un entier plus tard. Vous devriez également considérer si vous voulez ou non utiliser des doubles de manière cohérente.

0

Vous êtes en effet le passage d'un int à sqrt, qui ne prend que des arguments de type float, double ou long double. En outre, sqrt ne renvoie pas un int. Le compilateur ne peut pas deviner ce que la conversion de type à faire, alors vous devrez jeter vous-même en utilisant soit de style C ou lance « nouveau style » jette:

float k = sqrt((float)(...)); 
float k = sqrt(static_cast<float>(...)); 

En outre, indentent votre code correctement; cela rend la lecture beaucoup plus facile.

+1

Qu'est-ce que 'std :: dynamic_cast' ?? !! Et 'dynamic_cast '? –

+0

'dynamic_cast' ne fonctionnera pas sur un type sans fonctions virtuelles. Cela devrait être 'static_cast'. –

+0

@Fred: édité. Mon C++ est un peu éteint. – You

4

Il existe trois surcharges de sqrt qui prennent différents paramètres: float sqrt(float), double sqrt(double) et long double sqrt(long double). Vous pouvez les voir dans la sortie du compilateur.

Si vous appelez sqrt avec un paramètre entier, comme sqrt(9), un entier peut être lancé à toute de ces trois types. Alors, quelle fonction devrait être appelée? Le compilateur ne sait pas. C'est ambigu, donc vous obtenez une erreur pour vous forcer à choisir explicitement la surcharge que vous voulez. Juste cast le paramètre pour correspondre à l'une des surcharges comme ceci: sqrt(static_cast<float>(((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))).

+0

Apparemment, la situation actuelle avec la norme C++ appelle à sqrt (int) de convertir en un double sans avertissements de surcharge/erreurs. Voir la réponse de Shafik pour plus de détails: http://stackoverflow.com/a/19684955/446767 Cependant, étant donné que les versions du compilateur varient, la conversion en double peut toujours être une bonne idée. – Ted