sqrt和sqrtf之间的差异

时间:2011-09-15 12:44:05

标签: c++ floating-point

我想考虑编码。首先是:

#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相同?

5 个答案:

答案 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()接受doublefloatlong double,而sqrtf()只接受float }。

正如文档所说,有两个不同版本的唯一原因是因为C不支持重载,所以必须有两个函数。 C ++允许重载,因此实际上有三个不同版本的sqrt()采用各种大小的浮点参数。

所以在C ++中,你的代码片段基本上都是一样的。但是,在C上,float来电中会有double转换为sqrt()

答案 1 :(得分:3)

C不支持函数重载。这意味着每种类型必须有一个不同的功能。因此sqrtdoublesqrtffloat。由于double是C中浮点数的“首选”类型,因此“默认”版本是double的版本。两者都是math.h中C标准库的一部分。

在C ++中,应该使用重载的sqrt(在cmath中,在名称空间std中定义)。

答案 2 :(得分:3)

在C ++中,sqrt函数被重载以获取double,a floatlong double作为参数。当你传递int时,全部 可以调用三个,编译器无法选择一个 对其他人来说,这个电话很模糊。如果你明确转换 intfloat,当然,三者中的一个是精确匹配, 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。我使用了一些疯狂的编译器标志来突出我的硬件上的差异。除非你真的知道你在做什么,否则你应该使用更保守的旗帜。

相关问题