how to define which library to perform cos x - c++

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
}

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.)

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.

Related

Why can't I include the standard algorithm library after defining 'epsilon' in C++?

When I include the algorithm library before defining epsilon, the following code compiles:
#include <iostream>
#include <algorithm>
#define epsilon 0.00001
int main() {
std::cout << epsilon;
return 0;
}
When I switch them around, it doesn't:
#include <iostream>
#define epsilon 0.00001
#include <algorithm>
int main() {
std::cout << epsilon;
return 0;
}
It gives the following error 19 times:
epsilon_algorithm.cpp:3:17: error: expected unqualified-id before numeric constant
3 | #define epsilon 0.00001
|
On http://www.cplusplus.com/reference/algorithm/ and https://en.cppreference.com/w/cpp/algorithm there is no mention of anything named 'epsilon'. I know I can avoid the issue by simply always including <algorithm> before I define epsilon, I want to know what causes this error to broaden my understanding of C++ and prevent these types of errors in the future.
I compile with MinGW (32 bit, installed a few weeks ago) in an updated Windows 10 (64 bit) environment.
Standard library headers are allowed to include any other standard library header.
It's possible that <algorithm> includes <limits> and there exists std::numeric_limits::epsilon() there. And of course macros ignore namespaces and classes, so it would try to declare a function called 0.00001.
Don't use macros. Use C++ constants:
constexpr double epsilon = 0.00001;
And if you absolutely need macro, always define them after all includes. Defining them before makes your code very brittle - any change in those headers in the future might blow up your code with cryptic compiler errors.
Don't define macros in header files, for the same reason.
Prefer very localized macros when possible - define them where needed and #undef after you are done. This way they won't leak to the outside (although you can still inadvertently override an existing macro).

C++ using math.h for sin returns "too many arguments in function call"

The user inputs a number, which is converted from characters to a double (the number is is 0.0 before input where it is updated to any number). I should then be able to convert this and find the sin value. At the moment I get an error "too many arguments in function call". I understand I need to convert the users input into radian but I can't seem to find a work around.
Here is a snippet of the code (my Pi and Logarithm functions work okay)
Using public as the function is accessed from another class.
I've looked at a lot of sources but here are two that helped:
http://www.cplusplus.com/reference/cmath/sin/
http://www.cplusplus.com/forum/beginner/144006/
I know I'm missing something obvious but I can't seem to put my finger on it.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string>
#include <cmath>
class calculations {
public: double sin()
{
double radian = ((number1 * 180) / 2);
result = sin(radian);
return result;
}
}
Change the call to std::sin(radian). As written it's trying to call your sin function. Yours doesn't take any arguments, and it's being called with one argument, which is what the compiler is complaining about.

C++ --- Shouldn't these mathematical functions/constants be undefined?

I would not expect the following code that prints the value of sin(pi/2) to work, without the inclusion of an additional header:
#include <iostream>
int main()
{
std::cout << sin(0.5*M_PI) << std::endl;
return 0;
}
and, as expected, upon compilation I get an error reading ‘sin’ was not declared in this scope and a similar error for the use of M_PI.
However, I am confused by the fact that if I include seemingly any boost library header, take just for example the lexical_cast.hpp, and instead run
#include <iostream>
#include <boost/lexical_cast.hpp>
int main()
{
std::cout << sin(0.5*M_PI) << std::endl;
return 0;
}
then the code works and it prints 1.
Why should including this boost header, which contains no definition of M_PI or sin(), allow this constant and function to be defined? Shouldn't I need to include a header, like math.h that includes these things for this to work?
Yes, it should work that way.
The boost headers you tried all have implicit dependencies (pow(), modf(), fmod(), log() etc).
This is a common thing in the C++ compilation model. Nothing to be alarmed by.
Guideline: always explicitly include the headers you directly depend on. And only those.
This prevents portability issues on platforms where the library header dependency tree differs e.g. <algorithms> and <numeric> aren't implicitly included with some other standard library headers (e.g. MSVC)

C++ math functions can be used without including the directive "math.h" in VS 2013

I am very curious why I can use the math functions in C++ without including the "math.h". I can't find an answer with google search.
Here is the simple code I am executing. Everything is compiling and running.
#include <iostream>
using namespace std;
int main()
{
const float PI = acosf(-1);
cout << PI << endl;
return 0;
}
Any standard header is allowed to include any other standard header.
if you would compile the same with gcc-4.8 it would complain.
Keep in mind that this is not something to rely on if you want your code to be portable and compilable on different versions of the same or different compilers.

C++ Program Outputting Wrong Number

This is my program:
#include "stdafx.h"
#include <iostream>
using namespace std;
double areaofcircle(double r)
{
return 3.14 * r * r;
}
int main()
{
cout << areaofcircle(5);
}
I should be getting the output of "78.5" but I keep getting "78.512". What is going on?!
I've also tried float, but I still get the same output.
Also just a side question, do I really need to add "return 0;" to the main function?
One more side question, do I need to write "using namespace std;" inside every function, or can I just write it outside of everything, like how I've been doing it.
You're passing the literal for an integer (5) so somewhere an implicit conversion is required to turn it into a double. You would be better off passing 5.0. The C++ default for doubles requires no specifier so your 3.14 is fine. (specifying a float requires 3.14f). That said, I tried both with 5 and 5.0 and got 78.5 both times on my compiler.
How you're using the std namespace is fine, but as pointed out it does bring ALL of the standard namespace into scope. I see this a lot in teaching material. It is better to just use
using std::cout;
or just explicitly add std::cout to all uses. However, there is nothing "wrong" from a compilation standpoint in the way you did it.
I think you are doing something wrong. I tried the same on GCC compiler, and I do get 78.5. Which compiler are you using?
Regarding your other questions
It is always a good idea to return the state of your program from main. Usually, you can return EXIT_SUCCESS if everything works okay, else you can return EXIT_FAILURE.
No it is not necessary to include using namespace std. Instead, it is bad practice to pollute your standard namespace. You should include only those functions that you use very frequently.
To read more about C++. Check this link
Hope this helps.
Tried a few experiments on VS 2008 to see if I could get a similar error. By changing pi to a float I do get 78.500002622604370 which is different but not the same as your issue. But I do get 78.5 when pi is a double.
I'd recommend you let us know which compiler and version you're using, then possibly someone may be able to help.
#include "stdafx.h"
#include <iostream>
const double pi = 3.14;
double areaofcircle(double r)
{
return pi * r * r;
}
int _tmain(int argc, _TCHAR* argv[])
{
double temp = areaofcircle(5);
std::cout << temp;
return 0;
}