why is abs() in cmath also getting rid of my decimals?
math - Function abs() in C++ console project - Stack Overflow
c++ - Using #include <cmath>, why it always select the long version of abs instead of choose due to the input type? - Stack Overflow
performance - What is different about C++ math.h abs() compared to my abs() - Stack Overflow
Videos
Hey guys, I have a very simple code, which is the following:
#include <iostream>
#include <cmath>
int main()
{
double a = 2.1;
double b = abs(a);
std::cout << b;
}
The output I get is b=2. Which doesn't really make sense to me. The output should just be 2.1, no?
Thanks in advance!
Following overloads of abs are defined in both cstdlib and cmath headers, within namespace std and can be propagated to global namespace:
int abs( int n );
long abs( long n );
long long abs( long long n );
That's likely done to be consistent with different standards, e.g. POSIX stating them being declared in stdlib.h, and many of older C++ implementations declare some of those overloads in math.h because of C++98 inconsistency.
Currently, use of math.h in C++ is deprecated.
Note, none of those header files are considered "libraries" per se. They provide part of implementation, guaranteed by standard and likely are interface to runtime library or inline \ constexpr implementations.
Current draft offers as well
float abs(float j);
double abs(double j);
long double abs(long double j);
but current GCC implementation provides those in std namespace only.
Depends on your use case, In case you are doing competitive programming or you need to code your program really fast to test something small, then I prefer using <bits/stdc++.h> this will include all possible library functions in c++. But for all other cases I prefer using <cmath> becasue from a code reader point of view, this correctly implicates that I am doing something mathematical in this program. Performance wise, I dont think you could measure any difference on whatever you use.
Since they are the implementation, they are free to make as many assumptions as they want. They know the format of the double and can play tricks with that instead.
Likely (as in almost not even a question), your double is the binary64 format. This means the sign has it's own bit, and an absolute value is merely clearing that bit. For example, as a specialization, a compiler implementer may do the following:
template <>
double abs<double>(const double x)
{
// breaks strict aliasing, but compiler writer knows this behavior for the platform
uint64_t i = reinterpret_cast<const std::uint64_t&>(x);
i &= 0x7FFFFFFFFFFFFFFFULL; // clear sign bit
return reinterpret_cast<const double&>(i);
}
This removes branching and may run faster.
There are well-known tricks for computing the absolute value of a two's complement signed number. If the number is negative, flip all the bits and add 1, that is, xor with -1 and subtract -1. If it is positive, do nothing, that is, xor with 0 and subtract 0.
int my_abs(int x)
{
int s = x >> 31;
return (x ^ s) - s;
}