Подтвердить что ты не робот

Разница между 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?

4b9b3361

Ответ 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.