sqrt(int_value + 0.0) -- 它有什么作用吗?

7

我在一本非常奇怪的C++书中做作业,之前有人告诉我应该扔掉这本书,其中有一个非常奇特的代码片段。我知道作业总是会增加一些“神秘”的内容来试图让你困惑,比如在单语句for循环后缩进2行。但这个让我困惑的是因为它似乎有一些真正的用途。

基本上它是这样的:

int counter=10;
...
if(pow(floor(sqrt(counter+0.0)),2) == counter)
...

我尤其关注这一部分:

sqrt(counter+0.0)

这里的 +0.0 有什么作用?这是一种将数据强制转换为双精度浮点数的方式吗?这样做是为了避免某些我不使用的编译器发出警告吗?当我省略 +0.0 部分时,整个程序都打印了完全相同的东西,并在 g++ 上编译而没有警告。也许我没有使用够奇怪的编译器?
编辑:
此外,gcc 是否会违反标准并不对模棱两可的引用发出错误,因为 sqrt 可以接受 3 种不同类型的参数?
[earlz@EarlzBeta-~/projects/homework1] $ cat calc.cpp
#include <cmath>

int main(){
  int counter=0;
  sqrt(counter);
}
[earlz@EarlzBeta-~/projects/homework1] $ g++ calc.cpp
/usr/lib/libstdc++.so.47.0: warning: strcpy() is almost always misused, please use strlcpy()
/usr/lib/libstdc++.so.47.0: warning: strcat() is almost always misused, please use strlcat()
[earlz@EarlzBeta-~/projects/homework1] $

此外,这是我的系统库cmath的相关部分。我对模板不太熟悉,所以不确定它在做什么。
  using ::sqrt;

  inline float
  sqrt(float __x)
  { return __builtin_sqrtf(__x); }

  inline long double
  sqrt(long double __x)
  { return __builtin_sqrtl(__x); }

  template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                       double>::__type
    sqrt(_Tp __x)
    { return __builtin_sqrt(__x);

7
真正的问题是,为什么你还没有把这本书扔掉呢? :) - Justin Ardini
@Justin 这是学位必修课程,否则我肯定会烧掉每一页。 - Earlz
3个回答

13

这是将 int 转换为 double 的简易方法吗?

是的。

你不能使用一个 int 作为 sqrt 函数的参数,因为 sqrt 函数接受的参数类型为 floatdoublelong double。你需要将 int 转换为其中一个类型,否则函数调用会出现歧义。


1
但是为什么呢?在这种情况下甚至不需要。 - Earlz
5
我不知道为什么有人会建议使用+ 0.0。它唯一的好处就是比static_cast<double>(double)要少打几个字,但这不是使用它的好理由。 - James McNellis
1
@Earlz:这些重载函数都是C++标准库的一部分,自从语言被标准化以来就一直存在。在C标准库中,它们有不同的名称(因为必须有):sqrtfsqrtsqrtl。你可以通过查看你的cmath头文件很容易地找到它们。 - James McNellis
1
@Michael Burr:在VC 6附带的标准库中,sqrt(以及其他C风格的数学函数)的重载版本默认情况下被宏禁用。我不记得这个宏的名字,但无论如何,这就是为什么VC 6不会抱怨的原因。在VC 6中,默认情况下,sqrt的工作方式与C中的工作方式相同-它期望double类型,只有double类型。没有重载。 - AnT stands with Russia
1
@Earlz:它解释了为什么没有重载歧义。如果参数是整数类型,则函数模板用于选择sqrt(double)重载。我不认为这违反了库标准(也许会,但我怀疑)。尽管如此,这绝对是一种特定于实现的附加功能,如果您正在尝试编写可移植代码,则依赖它将是一个坏主意。 - James McNellis
显示剩余13条评论

0

表达式 counter + 0.0 的原因是明确将其转换为实数。如果我们不加 0.0,编译器会进行隐式转换。


0

这只是将整数转换为双精度浮点数的另一种方式。这是因为sqrt不接受整数。由于双精度浮点数更高,它将把整数合并到0.0中。同样的方法也可以用于将(int,double,float)转换为字符串。

double n = 0;

string m = ""+n;


2
我认为你在想其他编程语言;在C++中,你无法做到那样。 - James McNellis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接