2011-09-15 11 views
12

Chcę rozważyć kod. Pierwszy to:Różnica między sqrt i sqrtf

#include <iostream> 
#include <cmath> 
#include <math.h> 
using namespace std; 
int main() { 
    int s = 25; 
    cout << sqrt(s) << endl; 
    return 0; 
} 

Dało mi ten błąd:

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

Jeśli dodam typu float w nawiasach przed s tak:

#include <iostream> 
#include <cmath> 
#include <math.h> 
using namespace std; 

int main() { 
    int s = 25; 
    cout << sqrt((float)s) << endl; 
    return 0; 
} 

mam jak I zgaduję, 5. A inny wariant jest to, że zamiast sqrt, jeśli piszę sqrtf:

#include <iostream> 
#include <cmath> 
#include <math.h> 
using namespace std; 

int main(){ 
    int s=25; 
    cout << sqrtf((float)s) << endl; 
    return 0; 
} 

Dostałam też 5.

Jaka jest różnica między nimi? Czy to oznacza, że ​​sqrtf jest taki sam jak sqrt dla typu float?

+0

Ale nie dostaniesz błędu kompilujesz go w g ++ (kompilator GNU) – vivek

Odpowiedz

15

Oto a page on MSDN documentation for sqrt() and sqrtf(), że wyjaśnia różnicę:

sqrt, sqrtf

Oblicza pierwiastek kwadratowy.

double sqrt(
     double x 
    ); 
    float sqrt(
     float x 
    ); // C++ only 
    long double sqrt(
     long double x 
    ); // C++ only 
    float sqrtf(
     float x 
    ); 

Parametry

x: Wartość

Nieujemna zmiennoprzecinkowe Uwagi

C++ pozwala na przeciążenia, dzięki czemu użytkownicy mogą dzwonić przeciążeniem sqrt że podjęcie pływak lub długi podwójny typy. W programie C, sqrt zawsze przyjmuje i zwraca podwójne.

Return Value

sqrt zwraca pierwiastek kwadratowy-x. Jeśli x ma wartość ujemną, domyślnie sqrt zwraca wartość nieokreśloną.

Więc różnica w C++ jest to, że sqrt() akceptuje albo double, A float lub long double podczas sqrtf() akceptuje tylko float.

Jak mówi dokumentacja, jedynym powodem, dla którego istnieją dwie różne wersje, jest to, że C nie obsługuje przeciążania, więc musiały istnieć dwie funkcje. C++ pozwala na przeciążanie, więc w rzeczywistości istnieją trzy różne wersje sqrt() pobierające argumenty zmiennoprzecinkowe o różnych rozmiarach.

Tak więc w C++ oba fragmenty kodu są zasadniczo tym samym. W C jednak nastąpiłaby konwersja z float na w wywołaniu sqrt().

+0

jedno pytanie jeśli sqrt akceptuje podwójne to dlaczego działa po dodaniu typu float przed liczbą całkowitą? Czy nie powinno być podwójne? –

+0

"Różnica polega na tym, że sqrt() akceptuje podwójne" - tylko w C, w C++ jest przeciążone, aby zaakceptować dowolny typ FP. –

+0

@Matteo Italia: Prawidłowo. Powinienem to wskazać. –

3

C nie obsługuje przeciążania funkcji. Oznacza to, że dla każdego typu musi istnieć jedna inna funkcja. Stąd można uzyskać sqrt dla sqrt dla sqrt dla sqrt dla sqrt dla sqrt dla sqrt dla. Ponieważ double był typem "preferowanym" dla liczb zmiennoprzecinkowych w C, to "domyślną" wersją była wersja double. Oba są częścią standardowej biblioteki C, w math.h.

W języku C++ należy użyć przeciążonego sqrt (zdefiniowanego w cmath, w przestrzeni nazw std).

2

sqrtf jest dziedzictwo C

W C++ mamy przeciążenie, a funkcja sqrt ma różne przeciążenia dla trzech typów zmiennoprzecinkowych. W C zamiast tego nie ma przeciążania, dlatego różne wersje funkcji pierwiastka kwadratowego muszą być rozróżniane za pomocą nazwy funkcji; dlatego mamy sqrt (że w C działa tylko na double s) i sqrtf dla float s.

+3

Nigdy nie wiedziałem, że jest inaczej w Kanadzie! –

+0

@Paul: Tak dzieje się, gdy piszesz z telefonu z nadgorliwą autokorektą. :) –

+0

Heh - był tam ... ;-) –

3

w C++, funkcja sqrt przeciążony do podjęcia albo double, A float lub long double jako argument. Po przejściu pod numer int można wywołać wszystkie trzy i nie ma możliwości, aby kompilator wybrał jeden z nich jako inny , więc wywołanie jest niejednoznaczne. Jeśli jawnie przekonwertujesz na int na float, to oczywiście jedna z tych trzech jest dokładnym dopasowaniem, , dzięki czemu jest lepsza niż pozostałe dwie, więc zostaje wywołana.

Funkcja sqrtf pochodzi z C; w C nie ma przeciążenia; sqrt jest zawsze sqrt(double) i sqrtf ma float. Ponieważ ta funkcja nie jest przeciążona, wywołanie jej nie może spowodować niejednoznaczności.

+0

co oznacza, że ​​jeśli mam kod C++, nie muszę mieć sqrtf, prawda? –