对于一些非常大的双精度值,abs()返回一个负值
abs() returns a negative value for some very large double values
我使用了一些大的双值,所有的数学函数都很好。sqrt、pow和其他数学函数似乎对大的科学双值没有任何问题,但abs无法处理这些数字。例如,这是可以的:
double s = sqrt(3.9 * 1e32);
但这不是:
double s = sqrt(abs(3.9 * 1e32));
因为abs返回负值;我不明白为什么这个简单的函数不能处理科学的双重运算,而所有这些复杂的运算都很好。是我遗漏了什么,还是真的是这样,我不能使用c++abs函数来获得这样的值?
MCVE
#include <cstdlib>
#include <cstdio>
int main()
{
double d = 3.9e32;
double f = abs(d);
std::printf("%fn", f);
}
结果
- 大肠杆菌:
2147483647.000000
- g++4.8.3-密码:
-2147483648.000000
在此MCVE中,将abs
更改为std::abs
会由于过载解析失败而导致编译错误(无法在std::abs<int>
、std::abs<long>
和std::abs<long long>
之间进行选择)。
问题是,当您在C++中需要fabs(double)
或更好的std::abs()
时,您正在使用abs(int)
。你说你试过std::abs()
,但如果你有,它就会解决你的问题。
这是C++中一个不幸而常见的陷阱。在正面没有std::
的情况下,切勿使用abs()
。这很危险。
其他答案中提到的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的情况下调用abs
的int
版本,这将是实现的一个怪癖。实际上有一个DR处理这个问题
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2380
- 如何返回一个类的两个对象相加的结果
- 使用std::mt19937从字符串中返回一个随机单词
- PyRun_String返回一个NoneType对象
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- 返回一个带有 std::move 的对象并链接函数
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 函数可以应用于 std::optional,并返回一个可选值吗?
- readAll() 或 readAllStandardOutput() 在执行之前也返回一个空字符串
- Atmel Studio:返回一个包含数组的寄存器
- 返回一个计算了参数的函数
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 返回一个引用C++中另一个类对象的对象的有效方法
- 从类返回一个字符串 — 奇怪的行为
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 我正在尝试从 GMocked 类返回一个 rapidjson::值,但我似乎无法让它工作
- 实现一个函数,该函数将字符串作为输入并返回一个新字符串,辅音字母不替换为 "!"
- 错误 C4716"当事方::运算符+":必须返回一个值
- CStringArray::GetAt(int index) 返回一个 const. 为什么?
- 从system()调用G++会返回一个错误