I am receiving an error because of the following code :
const double angle = deg2rad(180);
The error says:
Function 'deg2rad' could not be resolved
I have recently installed 'Eclipse IDE for C/C++ Developers' and I have added -std=c++11 to Other flags at C/C++ Build/Settings/Tool Settings/GCC C++ Compiler/Miscellaneous
Any ideas what might be wrong?
The C++ standard library does not include a deg2rad function. You will need to create your own, or include a library which has one. An example of such a function is:
#include <cmath>
double deg2rad(double deg) {
return deg * M_PI / 180.0;
}
Note that M_PI is not actually part of the standard either, but is commonly included in the cmath header. If you are using Visual C++ you will need to define _USE_MATH_DEFINES to enable it.
There is no deg2rad() in the C++11 standard so, unless it's provided by some other library, you'll have to write your own. Something like this should do as a start:
double deg2rad (double degrees) {
return degrees * 4.0 * atan (1.0) / 180.0;
}
As per the above code, I normally leave micro-optimisations up to the compiler, such as letting it decide whether short functions should be inlined, or whether it will constant-fold the expression 4.0 * atan (1.0) / 180.0 into a single constant.
However, there may be a case in certain circumstances (such as if the compiler isn't as clever as the ones I use) to explicitly add the optimisations (keeping in mind that inline is a suggestion to the compiler rather than a demand):
inline double deg2rad (double degrees) {
static const double pi_on_180 = 4.0 * atan (1.0) / 180.0;
return degrees * pi_on_180;
}
C++ does not implement a deg2rad function, so you will need to write it by yourself.
inline double deg2rad(double deg)
{
return deg * M_PI / 180.;
}
Notice how we declare the function inline: This is because we don't want to waste extra assembly instructions setting up the call stack and jumping to the address of the function. When the function is inlined, it is substituted into the place it was called from. Note that inline is just advice to the compiler, and it is free to ignore it.
Related
I am writing a project in Visual Studio then I use GCC in order to compile it. Sometimes it causes some problems: This time I cannot use sqrtf function because VS accepts it however GCC does not. So I need to find some way (maybe mathematical approach to calculate square root) to find square root of some number in a way both GCC and VS will accept. To be more precise this is the line which causes a problem:
float x_f = circleRadius - sqrtf((float)((circleRadius * circleRadius) - (y * y)));
I need to find the square root of (circleRadius^2 - y^2)
std::sqrt solves this problem:
#include <cmath>
auto foo(int circleRadius, int y) {
float x_f = circleRadius - std::sqrt((float)(circleRadius * circleRadius - y * y));
}
compiles for both msvc and gcc according to https://godbolt.org/z/g9MJH6
You should prefer std::sqrt to sqrtf in C++. It works with more types, i.e., you could write your function more generically. It also does not use hungarian notation.
Edit: If you do not care if the calculation returns a float or a double, you could omit the cast and write the following:
auto x_f = circleRadius - std::sqrt(circleRadius * circleRadius - y * y);
If you care that a float is used, you can use std::sqrtf instead.
If you have to use a cast, you should generally prefer static_cast to C-style casts. Reasons for this are listed here.
Your situation may be if you use newer compiler at VC and older compiler at gcc.
Try to use sqrt or sqrtf WITH
#include <math.h>
Don't use
#include <cmath>
math.h should have sqrt, sqrtf definitions for both compilers.
I want to use exponential function which returns IEEE_FLOAT64 value
Currently I am using expf function, but still I am getting lots of warnings.
value = IEEEPosOne - (IEEE_FLOAT64)expf(value1);
From man 3 exp:
NAME
exp, expf, expl - base-e exponential function
SYNOPSIS
#include <math.h>
double exp(double x);
float expf(float x);
long double expl(long double x);
Link with -lm.
So just use exp().
//c++
#include <cmath>
double x = 7.0;//float64
auto y = std::exp(x);//exp(float64);
C++ standard provides appropriate overloads. No need to reflect operand type in function name.
This does answer does not apply to C only for C++
For C see #iBug's answer.
The C++ standard does not require an implementation to use the IEEE standard. Though this is usually the easiest floating point implementation to use as the chips are relatively standard in modern machines.
The standard provides a way to check using std::numeric_limits.
So if it is a requirement then you should validate.
#include <limits>
#include <iostream>
int main()
{
static_assert(sizeof(double) == 64);
static_assert(std::numeric_limits<double>::is_iec559());
// If the above compiles your double is IEEE 64 bit value.
// Or IEEE_754 compliant https://en.wikipedia.org/wiki/IEEE_754_revision
}
Now that you have established you are using IEEE values you can look at the cmath header to see that the functions there all take and return a double value.
exp
log
etc....
Note: You should note that Windows machines (usually) use an 80 bit floating point register (not 64). So things can get super whaky if you need strict compliance.
Note: Do NOT use:
expf() for float,
expl() for long double
These are for C library users where the language does not do the correct type checking. In C++ the language uses overloading to use the correct version of the function. If you look at the standard for exp:
Defined in header <cmath>
* float exp( float arg );
* double exp( double arg );
* long double exp( long double arg );
* double exp( Integral arg );
The above are all in the standard namespace.
std::cout << std::exp(100000.1) << "\n";
Notice that exp() can take any floating point type float, double or long double and generate the appropriate result type.
So I often see something like this:
#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
#define gf_PIhalf f32(3.14159265358979323846264338327950288419716939937510 * 0.5)
This means that half PI value is calculated every time I use gf_PIhalf in my code, right?
Wouldn't it be better to literally write the value of half PI instead?
Wouldn't it be even better to do the following:
#define gf_PI f32(3.14159265358979323846264338327950288419716939937510)
const float gf_PIHalf = gf_PI * 0.5f; // PIHalf is calculated once
Finally wouldn't it be best to do it like this (and why it doesn't seem to be a common practice):
const float gf_PI = 3.14159265358979323846264338327950288419716939937510;
const float gf_PIHalf = gf_PI * 0.5f;
This means that half PI value is calculated every time I use gf_PIhalf in my code, right?
Nope, not likely.
You can reasonably count on your compiler to do that multiplication at compile time, not runtime.
Your conclusions are somewhat right, except that the #define version will almost definitely resolve in compile time and the bit about types const globals being uncommon practice. They are common practice in modern good code. #defines are all but dead for this use. The best practice is to define your file scope globals in an unnamed namespace:
namespace
{
const float g_SomeGlobal = 123.456f;
}
This prevents anyone outside of your translation unit from being able to 'see' g_SomeGlobal.
I'm still only starting out in C++ and haven't dealt with much type casting yet. I was under the impression that the syntax is (type) (variables) however, this does not seem to work in this case.
float calcSphere (int radius)
{
float sphereSA;
sphereSA = (4 * PI * (radius*radius));
return sphereSA;
}
PI is a symbolic constant declared using #define PI 3.14 at the top of the code, I attempted to fix this problem by using (float) (4 * PI * (radius*radius)) but this did not solve anything. Google seems to return pretty obscure results on the subject too. Any solutions?
Just a guess but, are you getting a warning about initialization casting a double to a float (using MSVS)? Or possibly it's messing up b/c everything is ending up being cast as an integer b/c of the '4'?
If so, the problem is that when you type out a number it's a double. But you're using it as a float, to resolve it, that number needs to be what is cast. E.g.
sphereSA = ((float) 4 * (float) PI * radius * radius);
But, it would be better to give the compiler some type information about PI. E.g.
namespace MyConstants {
const float PI = 3.141;
}
sphereSA = ((float) 4 * MyConstants::PI * radius * radius);
You're using the C style cast. The syntax for casts has changed with C++.
You want to look for something like this:
dynamic_cast<something*>( yourthing );
i have this piece of code
bool Position::HasInLine(const Unit * const target, float distance, float width) const
{
if (!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance))
return false;
width += target->GetObjectSize();
float angle = GetRelativeAngle(target);
float absSin = abs(sin(angle));
return abs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width;
}
Problem i ran into is, that when i debug with gdb and try "p sin(angle)" it returns weird values - for angle 1.51423 it states that sin = 29 (so yes, i am putting in radians :-) ). More weird is, that when i try "p absSin" it always returns 0, and yes, i was on next line, so the "float absSin = abs(sin(angle))" line was already done.
Originaly there wasnt even included cmath, but the M_PI const was returning correct value, though i added #include at the start of the .cpp file just to make sure, but nothing changed.
If it helps, im using linux kernel 2.6.26-2-xen-amd64
Any ideas?
The function abs (as defined in cstdlib) always takes an integer and returns an integer. When dealing with doubles, you should be using fabs instead.
Another version of abs is defined in cmath (#include <cmath>). It is overloaded to accept (and return) both integers and doubles.
You may wish to double-check which version you are using.
shouldn't you be using fabs and not abs? abs takes ints and returns only ints
"for angle 1.51423 it states that sin = 29"
That's most probably an error of observation, not an error of the sin function.
The result should be in range -1 through +1.
Cheers & hth.,