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

Simone Margaritelli
  • 4,584
  • 10
  • 45
  • 70
  • 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. – old_timer May 16 '14 at 19:31
  • 1
    why so old version of gcc? – PiotrNycz May 16 '14 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. – Simone Margaritelli May 16 '14 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 :-) – Sergey Kalinichenko May 16 '14 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. – Simone Margaritelli May 16 '14 at 19:42
  • `but the point is that the whole project doesn't give me the expected results` So what is the magnitude of the differences between the two versions? Except for the first comment by dwelch, no mention of floating point's inherent inexact nature has been mentioned. MSVC has 3 floating point modes that can be chosen when building a program, `Precise`, `Strict`, and `Fast`. All of these could produce differing results, and that is for the same compiler, not differing compilers. – PaulMcKenzie May 16 '14 at 19:50
  • good point, I'm using (the default) /fp:precise on MSVC ... how can I achieve the same kind of results with gcc (if possible)? – Simone Margaritelli May 16 '14 at 19:53
  • @SimoneMargaritelli I don't know if it's even possible. Not only is floating point inexact, you have to guarantee that `exp` uses *exactly* the same implementation on MSVC and gcc. That is not guaranteed. When you're using such small numbers, inexactness of floating point and differences in implementation will make it difficult to get the exact results you're looking for. – PaulMcKenzie May 16 '14 at 19:57
  • that kind of sucks, I have to use a vm to develop this and I would like to publish the SVM library as opensource ... but if it's not working with the main opensource compiler there's no point in it :( – Simone Margaritelli May 16 '14 at 19:59
  • @SimoneMargaritelli Maybe you should write your own `exp` function. Then both compilers will be executing the same code. I know it's a pain, but at least you will get one guarantee (same implementation) that you're not getting now. – PaulMcKenzie May 16 '14 at 20:02
  • I would do that if I knew that exp is the real problem, but since the code is way much more complex than that, at this point I'm not even sure the (compiler) problem resides there ... – Simone Margaritelli May 16 '14 at 20:04
  • @PaulMcKenzie you know what? I've tried with /fp:strict and /fp:fast too ... I have the same (exact) results on msvc XD – Simone Margaritelli May 16 '14 at 20:27
  • Please do try with a more recent version of gcc. Also, please show the generated asm, to see if constant folding is involved. And do update your code snippet to something that actually compiles and demonstrates the problem. – Marc Glisse May 17 '14 at 17:28

2 Answers2

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
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?

neutrino2039
  • 126
  • 10
  • 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. – neutrino2039 May 16 '14 at 20:17
  • 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? – Simone Margaritelli May 16 '14 at 20:19
  • I'm using Visual Studio Professional 2012 on Windows, and Apple LLVM 5.0 in Mac OS. – neutrino2039 May 16 '14 at 20:26
  • 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 – Simone Margaritelli May 16 '14 at 20:27
  • I'm not sure how you are getting the error. The [MSDN documentation](http://msdn.microsoft.com/en-us/library/0ecbz014.aspx) 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](http://stackoverflow.com/questions/4264127/correct-format-specifier-for-double-in-printf). So, I guess, if you want more precision just use %le or %lg specifiers as pointed out by @dasblinkenlight. – neutrino2039 May 16 '14 at 20:45
  • the problem is not the printf specifier, even with the correct one I have different (wrong) results on the same exact code while MSVC compiled version gives correct result due to /fp:precise floating point model ... so now it's just a matter of "how do I replicate /fp:precise with GCC? – Simone Margaritelli May 16 '14 at 20:48
  • Also, I didn't see the problematic code and output in your Visual Studio snapshot. – neutrino2039 May 16 '14 at 20:50
  • dude are you reading what I'm writing you? It's not a matter of format specifier, that's old story now, the real issue is floating point model XD – Simone Margaritelli May 16 '14 at 20:51
  • O.o ... I made the second comment without refreshing the screen. By the way, I can guarantee that /fp:precise is not causing the output to differ either. Hope you find the answer soon. Would like to see your SVM implementation some day. – neutrino2039 May 16 '14 at 20:56
  • yeah even with others /fp models the output is always correct ... quite weird! – Simone Margaritelli May 16 '14 at 20:58