Consider the following C program:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main()
{
     double x = 0.5;
     printf("%f, %f\n", -expm1(x), 1-exp(x));
     exit(0);
}

If I compile this under mingw-w64-1.0-bin_i686-mingw_20110401.zip I 
get the correct:

-0.648721, -0.648721

However, if I compile it under mingw-w64-bin_i686-mingw_20110401.zip 
(or TDM's 4.5.2 build) I get

-0.271537, -0.648721

It seems that this is using a function from libmingwex.a, and that is 
faulty.  The code used would appear to be from 
mingw/mingw-w64-crt/math/expm1.def.h, and

   if (__FLT_ABI (fabs) (x) < __FLT_LOGE2)
     {
       x *= __FLT_LOGE2;
       __asm__ __volatile__ ("f2xm1" : "=t" (x) : "0" (x));
       return x;
     }

is simply wrong: you need

   if (__FLT_ABI (fabs) (x) < __FLT_LOGE2)
     {
       x /= __FLT_LOGE2;
       __asm__ __volatile__ ("f2xm1" : "=t" (x) : "0" (x));
       return x;
     }

since exp(x) - 1 is 2^(x/log(2)) - 1.

Brian Ripley

-- 
Brian D. Ripley,                  [email protected]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to