[英]abs vs std::abs, what does the reference say?
当心,我说的是::abs()
,而不是std::abs()
根据cplusplus.com 网站, abs
对于标准库的行为应该不同stdlib.
h C 版本,如果包含<cmath>
这是此页面的摘录(涉及::abs
,而不是std::abs
):
double abs (double x);
float abs (float x);
long double abs (long double x);
Compute absolute value
/*
Returns the absolute value of x: |x|.
These convenience abs overloads are exclusive of C++. In C, abs is only declared
in <cstdlib> (and operates on int values).
The additional overloads are provided in this header (<cmath>) for the integral types:
These overloads effectively cast x to a double before calculations
(defined for T being any integral type).
*/
真的???
在将程序移植到新平台时,我一直被这个问题困扰,因为不同的编译器和标准库的实现在这里有所不同。
这是我的示例程序:
#include <iostream>
//#include <stdlib.h>//Necessary inclusion compil under linux
//You can include either cmath or math.h, the result is the same
//#include <cmath>
#include <math.h>
int main(int argc, const char * argv[])
{
double x = -1.5;
double ax = std::abs(x);
std::cout << "x=" << x << " ax=" << ax << std::endl;
return 0;
}
这是 MSVC 2010 下的结果:
stdlib.h
程序也会编译:似乎无论您做什么,都始终包含math.h
和stdlib.h
x=-1.5 ax=1.5
(根据参考貌似正确)现在这是 OSX 下的结果:
-Wall
标志,也不会发出编译警告(未发出双精度转换为 int 的信号)! 如果将g++
替换为llvm-g++
,结果是相同的。 编译不需要包含math.h
或cmath
。x=-1.5 ax=1
最后是Linux下的结果:
stdlib.h
,程序将无法编译(最后,一个不自动包含stdlib
的编译器)。 对于 double -> int 强制转换,不会发出编译警告。x=-1.5 ax=1
这里没有明显的赢家。 我知道一个明显的答案是“更喜欢std::abs
到::abs
”,但我想知道:
abs
应该在std
命名空间之外自动提供双重版本时,它是不是就在这里?math.h
),这里所有的编译器及其标准库都错了吗?官方的参考文献说......这是一团糟。 前C ++ 11和C11:
正式,包括<cmath>
中介绍什么::
; 所有函数都在std::
。 实际上,只有export
不那么受尊重,不同的编译器做了很多不同的事情。 如果你包含<cmath>
,你使用std::
everywhere,或者你从编译器到编译器的变化。
C没有提供任何重载: abs
接受了一个int
,并在<stdlib.h>
声明, fabs
了double
,并在<math.h>
声明。
如果你在C ++中包含<math.h>
,你不清楚你得到了什么,但是因为没有任何实现者似乎关心标准(参见上面的第一点)......
粗略地说,要么包含<cmath>
,要么使用std::
作为所有用法的前缀,要么包含<math.h>
,如果你想要支持浮点(以及除int
以外的类型的各种后缀),则使用fabs
或double
)。
C ++ 11和C11增加了一些新的曲折:
现在允许<cmath>
(但不是必需的)在::
引入符号。 还有一件事可能因实施而异。 (这里的目标是使现有的实现符合要求。)
C有一个新的头文件<tgmath.h>
,它使用编译器魔术使<math.h>
的函数表现得像在C ++中一样重载。 (因此,并不适用于abs
,但只fabs
。)这个头没有被添加到C ++,明显的原因是C ++并不需要为这个任何编译器的魔力。
总而言之,情况变得更糟,我的建议仍然有效。 包括<math.h>
和<stdlib.h>
,并使用abs
/ fabs
及其派生的(例如labs
, fabsf
等),或者包含<cmath>
,并且只使用std::abs
。 还有别的,你会遇到可行性问题。
我被这个错误困扰了半天......:我在我的代码中使用了 abs(a double value):但结果不是预期的。 直到我将 abs 更改为 std.:abs(上面的双精度值)。 所有结果都匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.