C++ sqrt和sqrtf的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7431040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between sqrt and sqrtf
提问by dato datuashvili
I want to consider to code. First it is:
我想考虑编码。首先是:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt(s) << endl;
return 0;
}
It gave me this mistake:
它给了我这个错误:
>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 ==========
If I add type float in brackets in front of s, like this:
如果我在 s 前面的括号中添加类型 float,如下所示:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
int s = 25;
cout << sqrt((float)s) << endl;
return 0;
}
I got as I would guess, 5
. And another variant is that instead of sqrt
, if I write sqrtf
:
我得到了我的猜测,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;
}
I also got 5
.
我也得到了5
。
What is the difference between them? Does it means that sqrtf is same as sqrt for the float type?
它们之间有什么区别?这是否意味着 sqrtf 与 float 类型的 sqrt 相同?
回答by In silico
Here's a page on MSDN documentation for sqrt()
and sqrtf()
, that explains the difference:
这是关于sqrt()
and 的MSDN 文档页面sqrtf()
,它解释了不同之处:
sqrt, sqrtf
Calculates the square root.
double sqrt( double x ); float sqrt( float x ); // C++ only long double sqrt( long double x ); // C++ only float sqrtf( float x );
Parameters
x: Nonnegative floating-point value
Remarks
C++ allows overloading, so users can call overloads of sqrtthat take float or long double types. In a C program, sqrtalways takes and returns double.
Return Value
The sqrtfunction returns the square-root of x. If x is negative, sqrtreturns an indefinite, by default.
方格,方格
计算平方根。
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总是接受并返回 double。
返回值
的SQRT函数返回x的平方根。如果 x 为负数,sqrt默认返回一个不确定的值。
So the difference in C++ is that sqrt()
accepts either a double
, a float
or a long double
while sqrtf()
accepts only a float
.
因此,C++ 中的区别在于sqrt()
接受 a double
、 afloat
或long double
whilesqrtf()
仅接受 a float
。
As the documentation says, the only reason why there's two different versions is because C did not support overloading, so there had to be two functions. C++ allows overloading, so there are actually three different versions of sqrt()
taking floating point arguments of various sizes.
正如文档所说,有两个不同版本的唯一原因是因为 C 不支持重载,所以必须有两个函数。C++ 允许重载,因此实际上有三种不同版本sqrt()
的不同大小的浮点参数。
So in C++, both your code snippets do essentially the same thing. On C, however, there would've been a conversion from float
to double
in the sqrt()
call.
所以在 C++ 中,你的两个代码片段本质上都是一样的。在C,然而,就已经从一个转换float
到double
在sqrt()
通话。
回答by Etienne de Martel
C did not support function overloading. That means that there had to be one different function for each type. Hence a sqrt
for double
and sqrtf
for float
. Since double
was the "preferred" type for floating point numbers in C, then the "default" version was the one for double
. Both are part of the C standard library, in math.h
.
C 不支持函数重载。这意味着每种类型都必须有一个不同的功能。因此有一个sqrt
fordouble
和sqrtf
for float
。由于double
是 C 中浮点数的“首选”类型,因此“默认”版本是double
. 两者都是 C 标准库的一部分,在math.h
.
In C++, the overloaded sqrt
(defined in cmath
, in namespace std
) should be used.
在 C++sqrt
中cmath
,std
应该使用重载的(在, in namespace 中定义)。
回答by James Kanze
In C++, the sqrt
function is overloaded to take either a double
, a
float
or a long double
as argument. When you pass an int
, all
three can be called, and there's no way for the compiler to choose one
over the others, so the call is ambiguous. If you explicitly convert
the int
to float
, of course, one of the three is an exact match,
whcih makes it better than the other two, so it gets called.
在 C++ 中,该sqrt
函数被重载以接受 a double
、 a
float
或 along double
作为参数。当你传递一个int
,所有三个都可以被调用,编译器无法选择一个而不是其他的,所以调用是不明确的。如果您显式地将 转换int
为float
,当然,三个中的一个是完全匹配的,这使它比其他两个更好,因此它被调用。
The function sqrtf
is from C; in C, there is no overloading; sqrt
is
always sqrt(double)
, and sqrtf
takes a float
. Since this function
isn't overloaded, calling it can't result in an ambiguity.
函数sqrtf
来自C;在 C 中,没有重载;sqrt
总是sqrt(double)
,并且sqrtf
需要一个float
。由于此函数未重载,因此调用它不会导致歧义。
回答by Matteo Italia
sqrtf
is a heritage of C.
sqrtf
是 C 的遗产。
In C++ we have overloading, and the sqrt
function has different overloads for the three floating-point types. In C, instead, there's no overloading, thus the various versions of the square root function must be distinguished with the name of the function; hence we have sqrt
(that in C works only on double
s) and sqrtf
for float
s.
在 C++ 中,我们有重载,并且sqrt
函数对三种浮点类型有不同的重载。在 C 中,相反,没有重载,因此平方根函数的各种版本必须用函数名称来区分;因此我们有sqrt
(在 C 中只对double
s起作用)和sqrtf
对于float
s。
回答by ceilingcat
sqrtf()
is faster than sqrt()
sqrtf()
比 sqrt()
...but you pay a price in precision.
...但你付出了精确的代价。
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. I used some crazy compiler flags to highlight the difference on my hardware. Unless you really know what you're doing, you should probably use more conservative flags.
注意我使用了一些疯狂的编译器标志来突出我硬件上的差异。除非您真的知道自己在做什么,否则您可能应该使用更保守的标志。