2

for the whole day I've been fighting with something I believed being a bug but then (with some nasty printf-debugging) it came out that it was a weird exp math function behaviour ... maybe there's something I'm missing here because I really don't get it.

Could you please explain me the following behaviour:

#include <cmath> printf( "%lf\n", exp( -100.0 ) ); // <--- I know this should be %e, see the edit above 

gcc 4.2.1 ( both on mingw and Mac OS X, both 64bit ):

0.000000 

msvc 2012 ( 64bit )

3.720075....e-44 

( Where '....' are decimals I don't remember and can't test right now since I'm at home on my Mac ).

GCC flags:

g++ -Wall -g -pg *.cpp -o mytest 

MSVC with default flags.

What am I missing here? Isn't exp a standard function with standard precision?

EDIT 2

Ok this seems to be related to MSVC default floating point model ( /fp:precise ) ... any chance to have the same model with GCC ? I'd like to release the project as opensource but there's not point in it if it's not gonna work with the most popular opensource compiler due to a lack of precise floating point model.

EDIT

Ok so I was using a wrong format for the printf call ( I should've used %e or %.50lf to print scientific notation or enough decimals ), but the point is that the whole project doesn't give me the expected results ( I'm developing a SVM with SMO algorithm and Gaussian kernel ) if compiled with GCC, while it works flawlessly if I compile it with MSVC (of course with no changes whatsoever ). What could cause that?

( Picture of the same source code running on a Mac and on a VM with Windows 7 )

Picture of the **same** source code running on a Mac and on a VM with Windows 7

13
  • 2
    sure but you are relying on the C library to print it out and that is not a standard conversion. if you print the raw binary value for the floating point result, if the hardware conforms to the ieee spec, then you should get the same answer. but here again there are different rounding modes and different compilers or operating systems may have a different opinion on rounding. Commented May 16, 2014 at 19:31
  • 1
    why so old version of gcc? Commented May 16, 2014 at 19:32
  • @PiotrNycz I don't update gcc very often since it's not the compiler I use for my job, I was just playing around with it for a small Makefile based project. Commented May 16, 2014 at 19:33
  • What version of MSVC are you using? For a very long time, MSVC compilers have not been standard-compliant. Even now their conformance is spotty, although I think that most C99 is covered after only 15 years :-) Commented May 16, 2014 at 19:41
  • MSVC C support is ****ed up, I'm compiling it as C++ of course with visual studio 2012 updated to the latest revision. Commented May 16, 2014 at 19:42

2 Answers 2

7

The computations are the same, you are not printing enough digits:

printf( "%.50lf\n", exp( -100.0 ) ); 

This produces the following output with gcc:

0.00000000000000000000000000000000000000000003720076 

That's the 3.720076e-44

Using %le specifier produces 3.720076e-44, too.

Sign up to request clarification or add additional context in comments.

2 Comments

Alternatively, try using the "%e" format specifier
Or printf should use %lg to get the scientific notation if necessary. %lf should always be non-scientific.
0

I just compiled and executed

printf("%lf\n", exp(-100.0)); 

in my Dell Laptop (Windows 7, 64 bit and Visual Studio 2012) and my Macbook Pro (Mountain Lion, 64 bit and XCode). Both are displaying

0.000000 

as the result.

Are you sure, you didn't change the format specifier in Visual Studio?

10 Comments

I'm using the default /fp:precise flag with Visual Studio 2012 too and the output is consistent with Mac. Perhaps you should try running the code in a real PC, instead of VirtualBox. Also if want to publish your code as open source library, I guess you won't be going to use the printf functions (unless you want to show test cases) in them and just let the end user select appropriate precisions and appropriate format specifiers.
I've tried the code on a real pc (@ my office), I've used the VM just to show the differences while @ home .... what gcc and msvc versions are you using?
I'm using Visual Studio Professional 2012 on Windows, and Apple LLVM 5.0 in Mac OS.
I've an older gcc ( 4.2.1 ) ... btw I've tried with /fp:strict and /fp:fast too ... I have the same (exact) results on msvc XD
I'm not sure how you are getting the error. The MSDN documentation does not have any reference of %lf specifier. So I'm assuming that VS 2012 should just treat it as %f specifier (with 6 digit precision). Similar argument is made in this stackoverflow page. So, I guess, if you want more precision just use %le or %lg specifiers as pointed out by @dasblinkenlight.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.