Compile time warning


simbha
07-29-2011, 02:46 PM
Hello,

I am trying to link the NR library with my code and when I compile my code I get the following warning messages:

1>nrutil_nr.h(43) : warning C4244: 'return' : conversion from 'const double' to 'float', possible loss of data

1>nrutil_nr.h(468) : warning C4244: 'return' : conversion from 'double' to 'float', possible loss of data

1>nrutil_nr.h(469) : warning C4244: 'return' : conversion from 'double' to 'float', possible loss of data

1>nrutil_nr.h(470) : warning C4244: 'return' : conversion from 'double' to 'float', possible loss of data

1>nrutil_nr.h(471) : warning C4244: 'return' : conversion from 'double' to 'float', possible loss of data

On looking into the nrutil_nr.h file the problem seems to be in these lines

//some compilers choke on pow(float,double) in single precision. also atan2
inline float pow (float x, double y) {return pow(double(x),y);}
inline float pow (double x, float y) {return pow(x,double(y));}
inline float atan2 (float x, double y) {return atan2(double(x),y);}
inline float atan2 (double x, float y) {return atan2(x,double(y));}

I do understand that these warnings aren't a showstopper but still, what must I do to avoid these warning messages? Please do not ask me to suppress these messages because I these warnings are needed to ensure that I don't lose precision accidentally in my code.

I am using VC++ 2008 express and the CPP_211 legacy routines.

Thanks in advance

davekw7x
07-29-2011, 04:23 PM
...I get the following warning messages:
1>nrutil_nr.h(43) : warning C4244: 'return' : conversion from 'const double' to 'float', possible loss of data

Older versions of C++ nrutil_nr.h had the following line 43:

inline float SIGN(const double &a, const float &b)
{return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);}

Since a comes in as a double and it is assigned to the float return value, that warning can occur. It may or may not be benign, depending on the application.

Later versions of C++ nrutil_nr.h have the following line 43:

inline float SIGN(const double &a, const float &b)
{return b >= 0 ? (a >= 0 ? (float)a : (float)(-a)) : (a >= 0 ? (float)(-a) : (float)a);}


See how it goes? By putting the explicit casts on return values, the warnings go away.

Similar changes were made to the definitions of pow() and atan2(). The return type of standard library functions pow() and atan2() is double, so assigning that to the float value of the NR versions can give the warnings. Using a cast can eliminate the warning.

However...

If I were going to make any changes to the NR stuff, rather than using casts on places where double precision values are assigned to single precision floats, I would (probably) just make everything doubles. I mean, with any reasonable workstation compiler these days, floating point operations are all done with doubles anyhow. It actually takes more run time and code space to convert to floats.



Regards,

Dave

simbha
08-01-2011, 07:56 AM
Hello Dave,

Thanks for your help. I did try to put explicit casts in the return values, but I am still seeing the warning messages. I did the following changes to the NR code. Did I do it right or messed something up?

inline float SIGN(const double &a, const float &b)
{return b >= 0 ? (a >= 0 ? (float)a : (float)(-a)) : (a >= 0 ? (float)(-a) : (float)a);}

inline float pow (float x, double y) {return (float)pow(double(x),y);}

inline float pow (double x, float y) {return (float)pow(x,double(y)));}

inline float atan2 (float x, double y) {return (float)atan2(double(x),y);}

inline float atan2 (double x, float y) {return (float)atan2(x,double(y));}

Thanks

davekw7x
08-01-2011, 01:43 PM
...still seeing the warning messages. I did the following changes to the NR code. Did I do it right or messed something up?
Are you sure those were in your code? I mean, your second pow() function had an extra right parenthesis that kept it from compiling.

Anyhow...

Maybe you can try the following:

// Try it like this. Then change #if 1" to "#if 0" and try again

#if 1
#include <iostream>
#include <cmath>

inline float SIGN(const double &a, const float &b)
{return b >= 0 ? (a >= 0 ? (float)a : (float)(-a)) : (a >= 0 ? (float)(-a) : (float)a);}

inline float pow (float x, double y) {return (float)pow(double(x),y);}
inline float pow (double x, float y) {return (float)pow(x,double(y));} // <---Had an extra ')' here
inline float atan2 (float x, double y) {return (float)atan2(double(x),y);}
inline float atan2 (double x, float y) {return (float)atan2(x,double(y));}
using namespace std;

#else
#include "../other/nrutil_nr.h" // Use path name to your NR "other" directory
#endif


int main()
{
double x;
float y, z;

x = 1.2;
y = (float)3.4;

cout << fixed;
cout << "x = " << x << ", y = " << y << endl;
z = SIGN(x, y);
cout << "SIGN(x,y) = " << z << endl;

z = pow(x, y);
cout << "pow(x,y) = " << z << endl;

z = pow(y, x);
cout << "pow(y,x) = " << z << endl;

z = atan2(x, y);
cout << "atan2(x y) = " << atan2(x, y) << endl;

z = atan2(y, x);
cout << "atan2(y,x) = " << atan2(y, x) << endl;

return 0;
}


Do a command-line compile. Something like

cl test_util.cpp /EHsc

My version of Microsoft compiler came from Visual Studio 2008 Express (the free version), and gave no warnings.

Here's the output I got on my Windows XP workstation (same as when compiled with GNU g++):

x = 1.200000, y = 3.400000
SIGN(x,y) = 1.200000
pow(x,y) = 1.858730
pow(y,x) = 4.342849
atan2(x y) = 0.339293
atan2(y,x) = 1.231504


Same output when I changed "#if 1" to "#if 0" at the top of the program. (The nrutil_nr.h header contained the definitions in the form that I showed.)



Regards,

Dave

simbha
08-02-2011, 09:30 AM
Thank you Dave. It worked!!!! and the extra parenthesis was a typo i made and it wasn't there in the original code.