I am including math.h and cmath in my project.
I am looking into the differences between math.h and cmath.
I believe std::cos
would use cmath, but some literature seems to suggest that may not be the case.
How can I specify to use cos
function from math.h and not cmath?
#include <math.h>
#include <cmath>
...
double x;
int maxv = 1000000;
for(int i = 0; i < maxv; i )
{
x = static_cast<double>(i) / static_cast<double>(maxv);
printf("diff = %lf\n", cos(x) - std::cos(x)); // math.h vs cmath
}
CodePudding user response:
They are ordinarily the same function. The name of the library is libm
(“m” for “math”), like many other Unix systems, and you get the same function whether you access that function through the <math.h>
header or the <cmath>
header.
The actual way these headers work is kind of complicated. I will say that in this case, you are probably just getting the ordinary cos
function, no matter whether you call it through <math.h>
as cos(x)
or calling it through <cmath>
as std::cos(x)
.
Assembly
Here’s a test function. You can paste this into Godbolt (https://gcc.godbolt.org/) and follow along.
#include <cmath>
double my_function(double x)
{
return std::cos(x);
}
At -O2
, this becomes:
my_function(double):
jmp cos
Here’s another test function:
#include <math.h>
double my_function(double x)
{
return ::cos(x);
}
Here’s the result at -O2
:
my_function(double):
jmp cos
It is exactly the same. You get exactly the same function either way. It is just a different interface.
More Tests
#include <math.h>
#include <cmath>
#include <cstdio>
int main(int argc, char **argv) {
int maxv = 1000000;
for(int i = 0; i < maxv; i ) {
double x = static_cast<double>(i) / static_cast<double>(maxv);
std::printf("diff = %f\n", cos(x) - std::cos(x));
}
}
This prints diff = 0.000000
over and over again.
If you look at how the GCC optimizes this function, you’ll even see that it doesn’t actually call cos
twice—it calls cos
once, because it knows that the result will be the same both times. (It is unable to completely optimize out the call to cos
, maybe because it does not successfully determine that the output to cos
is finite in every loop iteration.)
CodePudding user response:
which library to perform cos x
Neither math.h
nor cmath
is a library. They are header files. They may be associated with a library, and may be considered part of a library product, but they are not the library. They declare functions the library provides and declare some additional things such as macros for constants and other things associated with the library.
I am including math.h and cmath in my project.
Do not do that. If you must do that, do not include them in the same files. In C files, use #include <math.h>
. In C files, using #include <cmath>
.
How can I specify to use
cos
function from math.h and not cmath?
The cos
declared by math.h
should be in the global namespace, so ::cos
should refer to it. However, the global namespace is sometimes polluted, either by historical implementations of <cmath>
that were sloppy or by programmer use of using namespace std
. (The cos
in <cmath>
should be in the std
namespace, so std::cos
should refer to it.) If you must get the cos
declared in <math.h>
, you can define a routine in a C source file that calls cos
and then call that C routine from your C code.
It is possible, even likely, these names will resolve to the same actual routine implementation.