2011-03-15  Kai Tietz  <ktietz@googlemail.com>

        * math/pow.def.h: Use log2l/exp2l and integer/fraction separation
        for improving calculation precission.



git-svn-id: svn+ssh://svn.code.sf.net/p/mingw-w64/code/trunk@4076 4407c894-4637-0410-b4f5-ada5f102cad1
diff --git a/mingw-w64-crt/ChangeLog b/mingw-w64-crt/ChangeLog
index 63c3381..8746e48 100644
--- a/mingw-w64-crt/ChangeLog
+++ b/mingw-w64-crt/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-15  Kai Tietz  <ktietz@googlemail.com>
+
+	* math/pow.def.h: Use log2l/exp2l and integer/fraction separation
+	for improving calculation precission.
+
 2011-03-12  Dongsheng Song  <dongsheng.song@gmail.com>:
 
 	* lib32/msvcr100.def (__report_gsfailure, _assert, _byteswap_uint64,
diff --git a/mingw-w64-crt/math/pow.def.h b/mingw-w64-crt/math/pow.def.h
index 3dbad96..438a4dd 100644
--- a/mingw-w64-crt/math/pow.def.h
+++ b/mingw-w64-crt/math/pow.def.h
@@ -160,7 +160,19 @@
   if (__FLT_ABI (modf) (y, &d) == 0.0 && (d <= (__FLT_TYPE) INT_MAX && d >= (__FLT_TYPE) INT_MIN))
      return __FLT_ABI (__powi) (x, (int) y);
   /* As exp already checks for minlog and maxlog no further checks are necessary.  */
-  rslt = __FLT_ABI(exp)(y * __FLT_ABI(log)(__FLT_ABI(fabs) (x)));
+  {
+    long double e1 = y * log2l ((long double) x);
+    if (fpclassify (e1) == FP_INFINITE)
+      rslt = (__FLT_TYPE) exp2l (e1);
+    else
+      {
+	long double fr, in;
+	in = modfl (e1, &fr);
+	rslt = (__FLT_TYPE) (exp2l (fr) * exp2l (in));
+      }
+    // rslt = __FLT_ABI(exp)(y * __FLT_ABI(log)(__FLT_ABI(fabs) (x)));
+  }
+
   if (signbit (x) && __FLT_ABI (modf) (__FLT_ABI (ldexp) (y, -1), &d) != 0.0)
     rslt = -rslt;
   return rslt;