Разница между sqrt и sqrtf
Я хочу рассмотреть код. Сначала это:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt(s) << endl;
return 0;
}
Это дало мне эту ошибку:
>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 ==========
Если я добавлю тип float в скобки перед s, вот так:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt((float)s) << endl;
return 0;
}
Я получил, как я предполагал, 5
. И еще один вариант заключается в том, что вместо sqrt
, если я пишу sqrtf
:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main(){
int s=25;
cout << sqrtf((float)s) << endl;
return 0;
}
Я также получил 5
.
В чем разница между ними? Означает ли это, что sqrtf такой же, как sqrt для типа float?
Ответы
Ответ 1
Здесь страница в документации MSDN для sqrt()
и sqrtf()
, которая объясняет разницу:
sqrt, sqrtf
Вычисляет квадратный корень.
double sqrt(
double x
);
float sqrt(
float x
); // C++ only
long double sqrt(
long double x
); // C++ only
float sqrtf(
float x
);
Параметры
x: неотрицательное значение с плавающей запятой
Примечания
С++ допускает перегрузку, поэтому пользователи могут вызывать перегрузки sqrt, которые используют float или long double. В программе C sqrt всегда принимает и возвращает double.
Возвращаемое значение
Функция sqrt возвращает квадратный корень x. Если x отрицательный, sqrt возвращает по умолчанию неопределенный.
Таким образом, разница в С++ заключается в том, что sqrt()
принимает либо double
, a float
, либо long double
, а sqrtf()
принимает только float
.
Как говорится в документации, единственная причина, по которой существуют две разные версии, состоит в том, что C не поддерживает перегрузку, поэтому должны быть две функции. С++ допускает перегрузку, поэтому на самом деле существуют три разные версии sqrt()
с аргументами с плавающей запятой различных размеров.
Итак, на С++ оба фрагмента кода делают по сути одно и то же. Однако на C было бы преобразование от float
до double
в вызове sqrt()
.
Ответ 2
C не поддерживает перегрузку функции. Это означает, что для каждого типа должна быть одна функция. Следовательно, a sqrt
для double
и sqrtf
для float
. Так как double
был "предпочтительным" типом для чисел с плавающей запятой в C, то "по умолчанию" была версия для double
. Оба являются частью стандартной библиотеки C, в math.h
.
В С++ следует использовать перегруженный sqrt
(определенный в cmath
, в пространстве имен std
).
Ответ 3
В С++ функция sqrt
перегружена, чтобы взять либо double
, либо
float
или long double
в качестве аргумента. Когда вы передаете int
, все
три могут быть вызваны, и нет возможности для компилятора выбрать один
над другими, поэтому вызов неоднозначен. Если вы явно конвертируете
от int
до float
, конечно, одно из трех является точным совпадением,
который делает его лучше, чем два других, поэтому он называется.
Функция sqrtf
взята из C; в C нет перегрузки; sqrt
всегда sqrt(double)
, а sqrtf
принимает a float
. Поскольку эта функция
не перегружается, вызов его не может привести к двусмысленности.
Ответ 4
sqrtf
- это наследие C.
В С++ у нас есть перегрузка, а функция sqrt
имеет разные перегрузки для трех типов с плавающей запятой. В C вместо этого нет перегрузки, поэтому различные версии функции квадратного корня должны различаться именем функции; следовательно, мы имеем sqrt
(что в C работает только на double
s) и sqrtf
для float
s.