我正在处理一些重要的双重值,并且所有数学函数都很好。似乎sqrt,pow和其他数学函数在重大科学双重值方面没有任何问题,但是abs无法处理这些数字。 例如,这没关系:
double s = sqrt(3.9 * 1e32);
但这不是:
double s = sqrt(abs(3.9 * 1e32));
因为abs返回负值; 我不明白为什么这个简单的功能无法处理科学的双重操作,当所有那些复杂的功能正常工作时。我是否遗漏了某些东西,或者它是真的这样,我不能使用c ++ abs函数来获取这些值?
#include <cstdlib>
#include <cstdio>
int main()
{
double d = 3.9e32;
double f = abs(d);
std::printf("%f\n", f);
}
2147483647.000000
-2147483648.000000
在此MCVE中,将abs
更改为std::abs
会因重载解析失败而导致编译错误(无法在std::abs<int>
,std::abs<long>
,{{之间进行选择1}})。
答案 0 :(得分:5)
当您在C ++ abs(int)
中需要fabs(double)
或更高版本时,问题是您正在使用std::abs()
。你说你试过了std::abs()
,但如果你有,那就解决了你的问题。
这是C ++中一个不幸的常见陷阱。切勿在前面使用abs()
而不使用std::
。这很危险。
答案 1 :(得分:3)
abs
在其他答案中提到的C ++中返回int
的说法完全不正确。在C ++标准库函数abs
中,为不同的参数(和返回)类型重载。标头<stdlib.h>
(或<cstdlib>
)为整数参数提供重载。标头<math.h>
(或<cmath>
)为浮点参数提供重载。
这种情况下的问题是OP在程序中使用的头文件。如果包含<math.h>
,则abs
应调用double abs(double)
并生成正确的结果(禁止编译器损坏)。如果包含<stdlib.h>
(并且没有<math.h>
),则由于abs(int)
和abs(long)
的可用性,调用应导致重载解析失败。
这同样适用于abs
和std::abs
。您应该使用哪一个仅取决于您包含的标题文件:<stdlib.h>
- <math.h>
或<cstdlib>
- <cmath>
。请注意,使用std::abs
代替abs
根本不会对此问题产生任何影响:在这两种情况下,重载函数集都是相同的。
如果在OP的情况下调用了int
abs
版本,那么这将是实现的一个怪癖。实际上有一个DR来处理这个问题
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2380