Home > Software design >  how to define which library to perform cos x
how to define which library to perform cos x

Time:01-14

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.

  •  Tags:  
  • c
  • Related