Why am I getting NaN when I should be getting a double? - c++

My problem is somewhere in the definition of first_x and second_x. When I call the quad_eq function, I get a -nan(ind) return based on the code below. If I change the .pushback() method parameter to be a literal integer, I get that integer returned instead of NaN. This leads me to believe that the problem is with my calculation/definition of first_x and second_x. Maybe there is some trick to C++ that I am not seeing or understanding. Can anyone see what my problem is? (If this helps I am working out of Bjarne Stroustrup's C++ Principles and Practice Using C++ where he gives me the std_lib_facilities.h file to use as I do not understand headers yet)
vector<double>quad_eq(double a, double b, double c) {
vector<double>answers;
double first_x = (-b + sqrt((b * 2) - (4 * a * c))) / 2 * a;
double second_x = (-b - sqrt((b * 2) - (4 * a * c))) / 2 * a;
answers.push_back(first_x);
answers.push_back(second_x);
return answers;
}

Depending on the input, you are taking the square root of negative numbers, so you get NaN (which is, in fact, a double) out of that, and any other operations propagate that.
Sidenote: the code you show doesn't compile as-is, because it is missing #include <vector> and using namespace std;. The latter is also usually frowned upon.

Related

What is the following C++ code used for -> "#define idiv(a, b) (((a) + (b) / 2) / (b))"?

I'm working with the code that frequently uses some nontrivial optimizations.
What is the
#define idiv(a, b) (((a) + (b) / 2) / (b))
used for? Why not simply
#define idiv(a, b) ((a)/(b) + 0.5)
Is it integer division overflow protection or something else?
Integer division truncates towards zero. Assuming (from the name of the macro, idiv) your arguments are of integer type, ((a)/(b) + 0.5) would be truncated before you got to the + 0.5, so you would always round down regardless.
(((a) + (b) / 2) / (b)) rounds up results greater than x.5, without using floating-point arithmetics.
Note: You tagged your question C++. In C++, you shouldn't "macro" anything, really. Check Marek's answer for a template solution (but also the caveat that it doesn't really work for negative values).
Your suggested modification is not equivalent, because a/b is integer division when the parameters are integers. You should cast parameters to floating point first.
The first macro avoids conversion to floating point, which might be faster. Additionally, converting values to floating point and back to integer might lose precision, because not all integers can be represented exactly as floats.
This code is C macro what is consider a very bad practice in C++.
In C++ you should use templates (some says that this is smarter macros).
template<typename T>
constexpr T idiv(T a, T b) {
return (a + b / 2) / b;
}
Still this code doesn't do what author has expected. Plan was to round result to closest integer value, but it fails if one arguments has negative value.
See this and note failure for a: 4 b: -2
And there is also integer overflow issue (see last test case).

sqrtf function alternative in Visual Studio

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.

Floating Point Representation in Debugger in C vs C++(CLI)

A little background: I was working on some data conversion from C to C# by using a C++/CLI midlayer, and I noticed a peculiarity with the way the debugger shows floats and doubles, depending on which dll the code is executing in (see code and images below). At first I thought it had something to do with managed/unmanaged differences, but then I realized that if I completely left the C# layer out of it and only used unmanaged data types, the same behaviour was exhibited.
Test Case: To further explore the issue, I created an isolated test case to clearly identify the strange behaviour. I am assuming that anyone who may be testing this code already has a working Solution and dllimport/dllexport/ macros set up. Mine is called DLL_EXPORT. If you need a minimal working header file, let me know. Here the main application is in C and calling a function from a C++/CLI dll. I am using Visual Studio 2015 and both assemblies are 32 bit.
I am a bit concerned, as I am not sure if this is something I need to worry about or it's just something the debugger is doing (I am leaning towards the latter). And to be quite honest, I am just outright curious as to what's happening here.
Question: Can anyone explain the observed behaviour or at least point me in the right direction?
C - Calling Function
void floatTest()
{
float floatValC = 42.42f;
double doubleValC = 42.42;
//even if passing the address, behaviour is same as all others.
float retFloat = 42.42f;
double retDouble = 42.42;
int sizeOfFloatC = sizeof(float);
int sizeOfDoubleC = sizeof(double);
floatTestCPP(floatValC, doubleValC, &retFloat, &retDouble);
//do some dummy math to make compiler happy (i.e. no unsused variable warnings)
sizeOfFloatC = sizeOfFloatC + sizeOfDoubleC;//break point here
}
C++/CLI Header
DLL_EXPORT void floatTestCPP(float floatVal, double doubleVal,
float *floatRet, double *doubleRet);
C++/CLI Source
//as you can see, there are no managed types in this function
void floatTestCPP(float floatVal, double doubleVal, float *floatRet, double *doubleRet)
{
float floatLocal = floatVal;
double doubleLocal = doubleVal;
int sizeOfFloatCPP = sizeof(float);
int sizeOfDoubleCPP = sizeof(double);
*floatRet = 42.42f;
*doubleRet = 42.42;
//do some dummy math to make compiler happy (no warnings)
floatLocal = (float)doubleLocal;//break point here
sizeOfDoubleCPP = sizeOfFloatCPP;
}
Debugger in C - break point on last line of floatTest()
Debugger in C++/CLI - break point on the second to last line of floatTestCPP()
Consider Debugger in C++/CLI itself is not necessarily coded in C, C# or C++.
MS libraries support the "R" format: A string that can round-trip to an identical number. I suspect this or a g format was used.
Without MS source code, the following is only a good supposition:
The debug output is enough to distinguish the double from other nearby double. So code need not print "42.420000000000002", but "42.42" is sufficient - whatever format is used.
42.42 as an IEEE double is about 42.4200000000000017053025658242404460906982... and the debugger certainly need not print the exact value.
Potential; similar C code
int main(void) {
puts("12.34567890123456");
double d = 42.42;
printf("%.16g\n", nextafter(d,0));
printf("%.16g\n", d);
printf("%.17g\n", d);
printf("%.16g\n", nextafter(d,2*d));
d = 1 / 3.0f;
printf("%.9g\n", nextafterf(d,0));
printf("%.9g\n", d);
printf("%.9g\n", nextafterf(d,2*d));
d = 1 / 3.0f;
printf("%.16g\n", nextafter(d,0));
printf("%.16g\n", d);
printf("%.16g\n", nextafter(d,2*d));
}
output
12.34567890123456
42.41999999999999
42.42
42.420000000000002 // this level of precision not needed.
42.42000000000001
0.333333313
0.333333343
0.333333373
0.3333333432674407
0.3333333432674408
0.3333333432674409
For your code to convert a double to text with sufficient textual precision and back to double to "round-trip" the number, see Printf width specifier to maintain precision of floating-point value.

Type casting/ conversion dilemma

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

Compile-time error with TurboC++

I am compiling with an old software TurboC++ 4.5(1995) and I am having some errors. Can anyone help?
#include<iostream.h>
#include<math.h>
void cal_root(int,int,int,float&,float&);
void main()
{
float root1=0,root2=0;
int a,b,c;
cout<<"Enter the three co-efficients of quadratic equation with spaces.\n";
cin>>a>>b>>c;
cal_root(a,b,c,root1,root2);
cout<<"The roots for given Quadratic Equation are "<<root1<<" & "<<root2<<".";
}
void cal_root(int a,int b,int c,float& root1,float& root2)
{
root1=-b+(sqrt((b*b)-4ac))/(2a); //error here
root2=-b-(sqrt((b*b)-4ac))/(2a); //error here
}
I'm getting the following error:
Function call missing ) in function cal_root(int, int, int, float&, float &)
at lines 16 and 17
You can't do multiplication like this:
4ac
2a
You have to spell it out:
4 * a * c
2 * a
But make sure you are liberal with your parenthesis, because, for example, 2 * a in that expression will first divide by 2, then multiply by a. When in fact, you want to divide by 2 and divide by a.
In fact, your -b is also badly placed, due to order of operations. The expression should look like this:
(-b + sqrt((b*b) - (4*a*c)))
/ (2*a)
You're not in a math class, you have to write out multiplications explicitly:
4ac -> 4*a*c
2a -> 2*a
You cannot leave operators as you would in algebra. 4ac and 2a should be 4*a*c and 2*a.
Also, get a better compiler / IDE. Turbo C++ was the worst piece of crap when I started programming about 10 years ago. It's still that bad. Use Netbeans for example.
The simple fact that it allows for void main() proves my point. Main should never be declared void.
You can't multiply variables by constants via 2x and the like, as it gets treated as a literal, 2, with a suffix of x, or whatever your variable happens to be, suffixes changing the representation of the variable (e.g. LL would treat it as a long long).
Instead, use operator*:
4 * a * c
2 * a
You can't write 4ac or 2a - this is not maths.
Change
4ac = 4*a*c
2a = 2*a
Also void main is wrong.
First of all
void cal_root(int a,int b,int c,float& root1,float& root2)
{
root1=-b+(sqrt((b*b)-4ac))/(2a); //error here
root2=-b-(sqrt((b*b)-4ac))/(2a); //error here
}
this should be written as
void cal_root(int a,int b,int c,float& root1,float& root2)
{
root1=-b+(sqrt((b*b)-(4*a*c)))/(2*a); //correction
root2=-b-(sqrt((b*b)-(4*a*c)))/(2*a); //correction
}
secondly avoid using void in main...(just a suggestion)