I was working with some big double values and all mathematical functions were fine. It seems that sqrt, pow and other math functions don't have any problems with big scientific double values, but abs can't handle these numbers. for example, this is ok:
double s = sqrt(3.9 * 1e32);
but this isn't:
double s = sqrt(abs(3.9 * 1e32));
because abs returns a negative value; I don't understand why this simple function can't handle scientific double operations when all those complex ones are working fine. Am I missing something or it's really this way and I can't use c++ abs function for such values?
#include <cstdlib>
#include <cstdio>
int main()
{
double d = 3.9e32;
double f = abs(d);
std::printf("%f\n", f);
}
2147483647.000000
-2147483648.000000
In this MCVE, changing abs
to std::abs
causes a compilation error due to overload resolution failure (can't choose between std::abs<int>
, std::abs<long>
, std::abs<long long>
).
The problem is you're using abs(int)
when you need fabs(double)
or better in C++, std::abs()
. You said you tried std::abs()
, but if you had it would have fixed your problem.
This is an unfortunate and common trap in C++. Never use abs()
without std::
on the front. It's dangerous.
The claim that abs
return int
in C++ mentioned in other answers is completely incorrect. In C++ standard library function abs
is overloaded for different argument (and return) types. Header <stdlib.h>
(or <cstdlib>
) provides overloads for integral arguments. Header <math.h>
(or <cmath>
) provides overloads for floating-point arguments.
The question in this case is which header file the OP used in the program. If <math.h>
was included, then abs
should have called double abs(double)
and generated a proper result (barring a broken compiler). If <stdlib.h>
was included (and no <math.h>
), then the call should have resulted in overload resolution failure due to availablity of both abs(int)
and abs(long)
.
This applies in equal degree to both abs
and std::abs
. Which one you should use depends only on what header files you include: <stdlib.h>
-<math.h>
or <cstdlib>
-<cmath>
respectively. Note that using std::abs
instead of abs
does not have any effect on this problem at all: the set of overloaded functions is the same in both cases.
If in the OP's case the int
version of abs
was called, it would be a quirk of the implementation. There's actually a DR that deals with this issue
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2380
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With