2010-11-18 11 views
2

Burada neden hata var?sq ++ 'de sorun 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; 
} 

Yapı çıkışı:

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 ========== 

cevap

4

sqrt (derleyici görünüşe göre çeşitli çiftler) çift sürer - bunu geçiyoruz bir int

sadece) sqrt ((çift yapmak .. ..)

Tamam - daha kesin olmak gerekirse, sqrt() bir kayan nokta numarası almalıdır - bir kayan nokta veya bir çift. Çeşitli tarihsel nedenlerden dolayı, genellikle farklı kayan nokta türleri arasında dönüşüm yapabilir. CPU'nuzun sqrt hesaplamasını yapması muhtemelen (x86'yı varsaymak) ne bir float ne de bir double/

+0

'sqrt', 'float', 'long double' ve 'double' için C++ 'da aşırı yüklenecek _required_'dir. (Bkz. 26.5 [lib.c.math]) –

+0

... ve "float" başka bir "double" değil. – You

+1

@You - sadece diyette olan bir çift. –

0

hesaplaması yaparken hesaplama yapmaktır. Üç sqrt metodu vardır: Biri uzun süren yüzer ve bir çift değer alır.

çift sürümünü kullanın ve sonra int geri dönüştürmek istediğiniz derleyici anlatmak için

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

deneyin.

4

bu parametre olarak int almaz

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

sqrt() çalışmalıdır.

+1

Yüzmek için iki kat tercih kullanın. Neden doğruluktan vazgeçersiniz ve FPU büyük olasılıkla zaten bir çift üzerinde çalışacak, sonra da hassas bir şekilde geri dönüşümü tekrar atmaya başlayacak. –

4

Tamsayı sqrt yapamazsınız. Kayan noktalı bir sayı olmalı.

Böyle bir şey yapmanız gerekir:

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

(çift) çift karınca (int) sonradan geri int dönüştürür int dönüştürecektir. Ayrıca, sürekli olarak çiftler kullanmak isteyip istemediğinizi düşünmelisiniz.

0

Yalnızca tip float, double veya long double savlarını alır sqrt, bir int geçen yürürlükte konum. Ayrıca, sqrt, int'u döndürmez. derleyici yapmak için ne tür dönüşüm tahmin edemez, yani ya C- stilini kullanarak atmalarını veya kendiniz dökme gerekecek "yeni stil" atmalarını:

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

Ayrıca düzgün kodunuzu girinti; okumayı çok daha kolaylaştırıyor. float sqrt(float), double sqrt(double) ve long double sqrt(long double):

+1

'std :: dynamic_cast' nedir? Ve dynamic_cast '? –

+0

'dynamic_cast', sanal işlevleri olmayan bir türde çalışmayacaktır. Bu static_cast olmalıdır. –

+0

@Fred: düzenlenmiş. C++'m biraz kapalı. – You

4

farklı parametreler alan sqrt üç aşırı yükler vardır. Bunları derleyici çıktısında görebilirsiniz.

Eğer bir tamsayı parametresi ile sqrt çağırırsanız

, sqrt(9) gibi bir tamsayı herhangi bu üç türde için dökülebilir. Yani hangi işlev çağrılmalıdır? Derleyici bilmiyor. Belirsizdir, dolayısıyla sizi istediğiniz aşırı yüklemeyi açıkça seçmek için zorlarsınız. Parametreyi, aşağıdaki gibi aşırı yüklenmelerden birine uydurun: sqrt(static_cast<float>(((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))).

+0

Görünüşe göre C++ standardı ile mevcut durum, sqrt (int) 'nin aşırı yüklenme uyarıları/hataları olmadan bir çift dönüştürülmesini gerektiriyor. Ayrıntılar için Shafik'in cevabına bakınız: http://stackoverflow.com/a/19684955/446767 Ancak, derleyici sürümleri değişeceğinden, oyuncu kadrosu ikiye katlamak için iyi bir fikir olabilir. – Ted