我想考虑编码。首先是:
#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 ==========
如果我在s前面的括号中添加float类型,如下所示:
#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与float类型的sqrt相同?
答案 0 :(得分:16)
这是a page on MSDN documentation for sqrt()
and 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 :非负浮点值
<强>说明强>
C ++允许重载,因此用户可以调用重载 采用float或long double类型的 sqrt 。在C程序中, sqrt 总是如此 接受并返回双倍。
返回值
sqrt 函数返回x的平方根。如果是x 为负数, sqrt 默认返回无限期。
因此,C ++的不同之处在于sqrt()
接受double
,float
或long double
,而sqrtf()
只接受float
}。
正如文档所说,有两个不同版本的唯一原因是因为C不支持重载,所以必须有两个函数。 C ++允许重载,因此实际上有三个不同版本的sqrt()
采用各种大小的浮点参数。
所以在C ++中,你的代码片段基本上都是一样的。但是,在C上,float
来电中会有double
转换为sqrt()
。
答案 1 :(得分:3)
C不支持函数重载。这意味着每种类型必须有一个不同的功能。因此sqrt
为double
,sqrtf
为float
。由于double
是C中浮点数的“首选”类型,因此“默认”版本是double
的版本。两者都是math.h
中C标准库的一部分。
在C ++中,应该使用重载的sqrt
(在cmath
中,在名称空间std
中定义)。
答案 2 :(得分:3)
在C ++中,sqrt
函数被重载以获取double
,a
float
或long double
作为参数。当你传递int
时,全部
可以调用三个,编译器无法选择一个
对其他人来说,这个电话很模糊。如果你明确转换
int
到float
,当然,三者中的一个是精确匹配,
whcih使它比其他两个更好,所以它被调用。
函数sqrtf
来自C;在C中,没有超载; sqrt
是
始终sqrt(double)
,而sqrtf
需要float
。由于这个功能
没有重载,调用它不会导致歧义。
答案 3 :(得分:2)
sqrtf
是C的遗产。
在C ++中我们有重载,sqrt
函数对三种浮点类型有不同的重载。相反,在C中,没有重载,因此必须使用函数的名称来区分平方根函数的各种版本;因此,我们sqrt
(在C中仅适用于double
s)和sqrtf
适用于float
s。
答案 4 :(得分:0)
sqrtf()
比sqrt()
...但你需要付出精确的代价。
C:\Users\ceilingcat> type f.cc
#include<iostream>
#include<cmath>
int main(){
double f=0;
int i=0;
for( ; i <= 2000000000; f+=sqrt(i++) );
std::cout.precision( 20 );
std::cout<<f<<'\n';
}
C:\Users\ceilingcat> cl f.cc /Ox /arch:AVX2 /fp:fast /Qfast_transcendentals
C:\Users\ceilingcat> time ./f.exe
59628479422355.53125
real 0m3.846s
user 0m0.000s
sys 0m0.015s
C:\Users\ceilingcat> type g.cc
#include<iostream>
#include<cmath>
int main(){
double f=0;
int i=0;
for( ; i <= 2000000000; f+=sqrtf(i++) );
std::cout.precision( 20 );
std::cout<<f<<'\n';
}
C:\Users\ceilingcat> cl g.cc /Ox /arch:AVX2 /fp:fast /Qfast_transcendentals
C:\Users\ceilingcat> time ./g.exe
59628479422157.773438
real 0m2.104s
user 0m0.000s
sys 0m0.000s
N.B。我使用了一些疯狂的编译器标志来突出我的硬件上的差异。除非你真的知道你在做什么,否则你应该使用更保守的旗帜。