- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
这是我的代码:
int f(double x)
{
return isnan(x);
}
如果我 #include <cmath>
我得到了这个程序集:
xorl %eax, %eax
ucomisd %xmm0, %xmm0
setp %al
这相当聪明:ucomisd如果 x 与自身的比较是无序的,则设置奇偶校验标志,这意味着 x 是 NAN。那么setp将奇偶校验标志复制到结果中(只有一个字节,因此 %eax
的初始清除)。
但是如果我 #include <math.h>
我得到了这个程序集:
jmp __isnan
现在代码不是内联的,__isnan
功能肯定是没有快的ucomisd
指令,所以我们已经引起了无益的跳跃。如果我将代码编译为 C,我会得到同样的结果。
现在,如果我更改 isnan()
调用__builtin_isnan()
,我得到了简单的 ucomisd
指令指令,无论我包含哪个 header ,它也适用于 C 语言。同样,如果我只是 return x != x
.
所以我的问题是,为什么 C <math.h>
header 提供了 isnan()
的效率较低的实现比 C++ <cmath>
标题?人们真的期望使用__builtin_isnan()
,如果是,为什么?
我使用 -O2
在 x86-64 上测试了 GCC 4.7.2 和 4.9.0和 -O3
优化。
最佳答案
看<cmath>
对于 gcc 4.9 附带的 libstdc++,您会得到:
constexpr bool
isnan(double __x)
{ return __builtin_isnan(__x); }
一个 constexpr
函数可以积极内联,当然,该函数只是将工作委托(delegate)给 __builtin_isnan
.
<math.h>
header 不使用 __builtin_isnan
,而是使用 __isnan
在这里粘贴的实现有点长,但它是 math.h
的第 430 行在我的机器上™。由于 C99 标准要求对 isnan
使用宏等(C99 标准的第 7.12 节)“功能”定义如下:
#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \
: sizeof (x) == sizeof (double) ? __isnan (x) \
: __isnanl (x))
但是,我看不出它为什么不能使用 __builtin_isnan
而不是 __isnan
所以我怀疑这是一个疏忽。正如 Marc Glisse 在评论中指出的那样,有一个 relevant bug report对于类似的问题,使用 isinf
而不是 isnan
.
关于c++ - 为什么 GCC 对 C++ <cmath> 比 C <math.h> 更有效地实现 isnan()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26052640/
我很困惑为什么这段代码没有包含就可以工作 "#include " 下面是我的代码,没有它也能正常工作。 // PowerApp.cpp : Defines the entry point for th
我编写了一个利用 Fast Light Toolkit 的小程序,但由于某种原因,在尝试访问 cmath header 中的函数时会生成编译器错误。 如错误::acos has not been de
所以我最近在尝试涉及浮点运算的问题。下面是该代码的一个片段。 #include #include typedef unsigned long long ull; int main(){ lon
我正在用 clang 编译我的项目,但我遇到了一个奇怪的错误: [ 1%] Building CXX object CMakeFiles/tfs.dir/src/actions.cpp.o In fi
嘿伙计们(还有姑娘们),我正在做我的家庭作业,除了我不知道如何使用 cmath 库中的函数之一将两个方程合并为一个之外,我已经完成了大部分。我将复制并粘贴作业说明,然后是我的代码和我遇到困难的部分。粗
我可以使用 C++ 中的任何方法(例如重载或模板化)来允许我将类实例作为参数传递给 cmath 函数吗?例如,如果我有一个名为 “Point” 的类(如下所示),有什么方法可以执行操作 std::ab
嘿,所以我设法在我编码的一些图形数学中找到了问题,显然当我到达这行代码时:float test3= asin(test2); where test2= 0.017409846。 根据我的理解,“asi
我的问题是:有没有办法在提供单精度或 double 参数时始终使用数学函数的扩展精度版本 - 例如 sqrt、exp 和 &c - 而无需使用显式转换? 例如我想要这个功能,没有转换的麻烦: floa
我正在尝试使用 GLM 与 Vulkan/SDL 配合使用。我这两个都工作正常,但是当我选择构建时,它说 /usr/include/c++/7.1.1/cmath:45: error: math.h:
如何在不使用 cmath 的情况下获取两个 double 类型输入的底数:如果第一个输入为负但不适用于不确定哪里出错的正整数,这就是它的工作原理?任何见解表示赞赏..谢谢 int main() {
数学函数的命名空间是什么?全局还是 std? 考虑 cos功能。它有 3 个重载。但也有来自 math.h 的遗留 cos。 C 对函数重载一无所知。因此 cos(x) 无法解析为 cos(float
我想创建一个映射,其键是作为字符串的函数名称,值是函数本身。所以像这样... #include #include #include #include typedef std::function
给定以下用户定义的类型 S,它具有到 double 的转换函数: struct S { operator double() { return 1.0;} }; 以及以下对 cmath 的调用使用
以下程序编译正确: #include int main(int argc, char *argv[]) { return int(log(23.f)); } (在带有标志 -std=c++1
我曾经使用 math.h 没有任何问题。现在,我使用一个外部库,它本身有一个名为 math.h 的文件。 ,但其中包括 . 将此库添加到我的项目中(或者甚至只是添加包含目录,而不涉及代码)现在会从
我得到了名为 y0 的变量并包含 cmath,当使用不带任何参数的 g++ 编译它时,出现编译错误 错误:“double(double) throw ()”和“double”类型的操作数对二进制“op
我正在尝试学习 C++,并且正在使用 MS Visual Studio 2019。我有以下代码: #include int main() { std::cout 的 header 标题。
我使用 ppa:deadsnakes/ppa 存储库在 ubuntu 上安装了 python3.7。 当我尝试运行时 import cmath 在 python shell 中失败并显示消息: Mod
嘿,所以我正在做一些图形数学并插入我认为是 float 的东西(我很确定我事先操纵 float 的方式不知何故搞砸了 ...)进入功能并得到奇怪的负面结果。 例如当 Angle 初始等于 350.0
我正在使用 OpenGL ES 2 创建一个 iPhone 应用程序,它同时使用 objective-c 和 c++。其中有一个用于定义一些 vector 属性的头文件,该文件包含导致错误的cmath
我是一名优秀的程序员,十分优秀!