Asked by:
Issues with Math functions in Visual Studio Versions
Question

#include "string.h"
#include "math.h"
int main ()
{
double result = (double)sqrt(2.3456F);
unsigned char data[8]; //holds the bytes of the result
memmove(data,&result,8);
for(int i=0;i<8;i++)
printf("%d\n",data[i]);
return 0;
}The above same code convert the sqrt() result to double and then stores in another double variable. Here the data holds the binary representation of the floating point number result.The same code when run on Visual C++ 6.0 and Visual C++ 2010 gives different results. Why is this so?
and one more thing is If the result had been a float then Visual C++ 6.0 and Visual C++ 2010 are giving the same value for the result.
Can any body sort out this??
Output with result variable being double::
with Visual C++ 6.0
byte representation of result variabledata::
[0] 196 'Ä'
[1] 12 ''
[2] 25 ''
[3] 254 'þ'
[4] 42 '*'
[5] 129 ''
[6] 248 'ø'
[7] 63 '?'with Visual C++ 2010
data::
[0] 0 unsigned char
[1] 0 unsigned char
[2] 0 unsigned char
[3] 0 unsigned char
[4] 43 '+' unsigned char
[5] 129 '' unsigned char
[6] 248 'ø' unsigned char
[7] 63 '?' unsigned charOutput with result variable being float::
with Visual C++ 6.0
[0] 88 'X'
[1] 9 ' '
[2] 196 'Ä'
[3] 63 '?'with Visual C++ 2010
I got the same binary value for result variable as above.
MaheshWednesday, January 11, 2012 11:43 AM
All replies

It seems VC6 handles the sqrt different to VC2010. VC6 takes the double version of sqrt, in your particualr example VC2010 takes the float version in my opinion.
If you change the line with your calculation to:
double result = (double)sqrt(2.3456);
the result seems a double value and not a (to double) casted float value.Wednesday, January 11, 2012 11:53 AM 
No,I have checked VC6 is using float version of sqrt only.But one thing i observed is VC2010 does not have float versions of the math functions.So VC2010 might be using double version of sqrt and VC6 might be using float version of sqrt. Could that be reason for this difference in the results for the same code on different versions??Correct me if i am wrong.
MaheshWednesday, January 11, 2012 12:02 PM 
Wednesday, January 11, 2012 1:10 PM

I have a few things to point out..
sqrt(2.3456F); defines a 4 byte single precision float, this gets converted to a double that the c library function sqrt accepts. Result is a double 8 byte number. A better way to tell the compiler what you want is to include types:
const double n = 2.3456; // now this is a true double
Another thing to check would be the compiler setting for "Floating Point Model" on both versions, to check for differences. Clearly from you message, you got a float, 4 byte version of the sqrt function. That should have required using the sqrtf function. I would also try the cmath.h library for any differences also, as this would be a c++ conforming library.
QuickCWednesday, January 11, 2012 9:34 PM 
Mahesh Punna wrote:>>#include "string.h">#include "math.h">>int main ()>{> double result = (double)sqrt(2.3456F);> unsigned char data[8]; //holds the bytes of the result>> memmove(data,&result,8);> for(int i=0;i<8;i++)> printf("%d\n",data[i]);> return 0;>}>>The above same code convert the sqrt() result to double and then stores>in another double variable.Nope, that's not what happens. In VC 2008 and 2010, your program calls thefunction sqrtf, which takes a float and returns a float. Check the sourcefor <math.h>. There is an inline overload of sqrt that takes a float, andcalls sqrtf instead.The floattodouble conversion merely adds zeros. That explains yourresult.Tim Roberts, timr@probo.comProvidenza & Boekelheide, Inc.
Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.Friday, January 13, 2012 7:36 AM 
@Tim Rpberts: I have checked in VC6 and VC2010 have same type of calls for sqrt() and sqrtf() in math.h
Mahesh Edited by Mahesh Punna Friday, January 13, 2012 10:43 AM
Friday, January 13, 2012 10:43 AM 
Mahesh Punna wrote:>>@Tim Rpberts: I have checked in VC6 and VC2010 have same type of calls for sqrt() and sqrtf() in math.hNo, not exactly. In VC6, the inline overload for (float)sqrt(float) isonly defined if the symbol _MSC_EXTENSIONS is not defined. By default,that symbols IS defined. If you check the compiled code (/FAsc), you'llsee that the compiler immediately promotes your float constant to a double,then calls the original sqrt that takes a double and returns a double.If you #undef _MSC_EXTENSIONS, the code in VC6 is similar to VC2010 butagain not identical, and the difference is subtle. The toplevel codebasically does this:FLD DWORD (load your constant as a float)FSTP DWORD (push your constant on the stack as a float)CALL ?sqrt@@YAMM@ZFSTP QWORD (store double result in your buffer)?sqrt@YAMM@Z eventually calls the _sqrtf function in both versions. InVC2010, the _sqrtf function does this:FLD DWORD (load argument as a float)FSTP QWORD (store it as a double)FSQRT (do doubletodouble sqrt)FSTP DWORD (store only the top 32bits in memory)FLD QWORD (load that float as a double)It promotes the float to a double, does the square root, then stores thedouble result but reloads as a float. So, the top of the stack getstruncated to a float, and the FSTP in the toplevel code gets a float valuewith the bottom 32 bits zero.In VC6, the _sqrtf function does this:FLD DWORDFSTP QWORDFSQRTFST DWORDIt stores the double result, but it leaves the top of the stack at fullprecision. By the time it gets back to the toplevel, the top of stackstill has all 64bits of precision.So, I think you could argue this was a bug in VC6 that has since beencorrected.Tim Roberts, timr@probo.comProvidenza & Boekelheide, Inc.
Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.Saturday, January 14, 2012 11:50 PM 
@Tim Roberts,Thanks for your reply.What would suggest me to make math function sqrt to have the same in both VC6 and VC2010.
Shall I convert the float to double and before calling sqrt() function in VC2010?? (i.e sqrt((double) floatvariable ))
Or any possible way to make VC2010 sqrt() produces the same results as VC6 without making any changes to VC6 code?
MaheshMonday, January 16, 2012 5:19 AM 
Mahesh Punna wrote:>>@Tim Roberts, Thanks for your reply.What would suggest me to make>math function sqrt to have the same in both VC6 and VC2010.In what universe would it possibly matter?>Shall I convert the float to double and before calling sqrt()>function in VC2010?? (i.e sqrt((double) floatvariable ))That should give you the same result, but it would have been quicker to tryit yourself.Tim Roberts, timr@probo.comProvidenza & Boekelheide, Inc.
Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc. Proposed as answer by Fredrick_V Thursday, March 22, 2012 9:02 PM
Tuesday, January 17, 2012 4:50 AM