sqrt(float) 有标准返回类型吗?

问题描述 投票:0回答:1

我注意到,当将浮点输入传递给

cmath
sqrt
时,appleclang++ (v14.0.0) 似乎返回单精度浮点。当切换到 gcc/clang 时,我很惊讶地得到了不同的结果。

这是我的最小可重现示例:

#include <cmath>
#include <cstdio>
#include <type_traits>

int main()
{
  float f = 1+1e-7;
  auto X = sqrt(f);
  printf("%16s says X is a %6s with value: %0.17g\n",
#ifdef __clang__
#if defined(__apple_build_version__)
    "appleclang++",
#else
    "clang++",
#endif
#elif __GNUC__
    "g++",
#else
    "unknown compiler",
#endif
    std::is_same<float, decltype(X)>::value ? "float" : "double",
    X);
}

对于不同的编译器,我看到:

    appleclang++ says X is a  float with value: 1
         clang++ says X is a double with value: 1.000000059604643
             g++ says X is a double with value: 1.000000059604643

我正在使用

-std=c++11
进行编译,只是为了确定

如果我切换到

std::sqrt

,那么每个人都同意这是一个浮动,但我仍然很好奇。 
sqrt
 的这种行为确实是由编译器决定还是 appleclang 是非标准的?

c++ sqrt cmath c-standard-library
1个回答
0
投票
问题是您使用全局命名空间范围中的

sqrt

,这是错误的。应该是
std::sqrt

当包含

<cmath>

 时,只能保证 
std::sqrt
 的所有重载都在 
std::
 命名空间范围内提供。您需要包含 
<math.h>
 以保证所有重载在全局命名空间范围内也可用。

当包含不匹配时,未指定哪些重载将可见,然后有可能不是获得

float sqrt(float)

 重载,而是获得 
double sqrt(double)
 重载,或任何其他重载,例如期望 和 
int
 并返回 
double
(这会导致非常奇怪的结果)。

© www.soinside.com 2019 - 2024. All rights reserved.