2010-11-18 3 views
2

Почему здесь ошибки?sqrt problem in 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; 
} 

Сложение выход:

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

ответ

4

SQRT принимает двойные (по-видимому, различные различные двойники в вашем компиляторе) - вы передаете ему ИНТ

вобще SQRT ((двойной) .. ..)

ОК - если быть более точным, sqrt() должен принимать число с плавающей запятой - либо поплавок, либо двойной. По разным историческим причинам он, как правило, способен преобразовывать разные типы с плавающей запятой. Вероятно, бит вашего процессора, выполняющий расчет sqrt (предположим x86), выполняет расчет в 80 бит, который не является ни поплавком, ни двойным/

+0

'sqrt' _required_, чтобы быть перегруженным для' float', 'long double' и' double' в C++. (См. 26.5 [lib.c.math]) –

+0

... и 'float' не является« еще одним «двойным». – You

+1

@You - это просто двойной, который был на диете. –

0

Существует три метода sqrt: один, который занимает длинный, float и один, который принимает двойное значение.

Попробуйте

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

, чтобы сообщить компилятору, что вы хотите использовать двойную версию, а затем преобразовать обратно в междунар.

4

это должно работать

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

SQRT() не принимает INT в качестве параметра.

+1

Используйте double, чтобы плавать. Зачем отдавать точность, и FPU, вероятно, будет работать на двойнике в любом случае, а затем выбросить точность преобразования обратно в float. –

4

Вы не можете взять sqrt целого числа. Он должен быть числом с плавающей запятой.

Вам нужно сделать что-то вроде этого:

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

The (двойной) преобразует Int двойному муравья (INT) преобразует его обратно в междунар впоследствии. Вы должны также рассмотреть вопрос о том, хотите ли вы последовательно использовать удвоения.

0

Вы фактически передавая int к sqrt, который только принимает аргументы типа float, double или long double. Кроме того, sqrt не возвращает int. Компилятор не может угадать, что преобразование типа, чтобы сделать, так что вам придется бросить его самостоятельно либо с помощью C-стиле бросает или «новый стиль» бросает:

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

Кроме того, отступы ваш код правильно; это делает чтение намного проще.

+1

Что такое 'std :: dynamic_cast' ?? !! И 'dynamic_cast '? –

+0

'dynamic_cast' не будет работать над типом без виртуальных функций. Это должно быть 'static_cast'. –

+0

@Fred: отредактировано. Мой C++ немного выключен. – You

4

Есть три перегрузки sqrt, которые принимают различные параметры: float sqrt(float), double sqrt(double) и long double sqrt(long double). Вы можете увидеть их на выходе компилятора.

Если вы звоните sqrt с целочисленным параметром, как sqrt(9), целое число может быть приведен к любому из этих трех типов. Итак, какую функцию следует назвать? Компилятор не знает. Это неоднозначно, поэтому вы получаете ошибку, вынуждающую вас явно выбирать перегрузку, которую вы хотите. Просто введите параметр в соответствие с одной из перегрузок, например: sqrt(static_cast<float>(((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y))).

+0

Очевидно, что текущая ситуация со стандартом C++ вызывает sqrt (int) для преобразования в double без предупреждений/ошибок перегрузки. См. Ответ Shafik для получения дополнительной информации: http://stackoverflow.com/a/19684955/446767 Однако, поскольку версии компилятора будут различаться, приведение к удвоению может быть хорошей идеей. – Ted