Alex Henrie : msvcrt: Set the correct error number in pow(f).

Alexandre Julliard julliard at winehq.org
Mon Sep 18 14:43:49 CDT 2017


Module: wine
Branch: master
Commit: 3864851feb1a8a76a8665dea0484512f1fc13c8c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3864851feb1a8a76a8665dea0484512f1fc13c8c

Author: Alex Henrie <alexhenrie24 at gmail.com>
Date:   Thu Sep 14 09:16:57 2017 -0600

msvcrt: Set the correct error number in pow(f).

Old versions of MSVC set EDOM on pow(-1, INFINITY) and
pow(-1, -INFINITY) but new versions do not.

Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/math.c         | 12 ++++++++----
 dlls/ucrtbase/tests/misc.c | 23 +++++++++++++++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 05a2b72..60ce4e6 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -318,9 +318,11 @@ float CDECL MSVCRT_log10f( float x )
  */
 float CDECL MSVCRT_powf( float x, float y )
 {
-  /* FIXME: If x < 0 and y is not integral, set EDOM */
   float z = powf(x,y);
-  if (!finitef(z)) math_error(_DOMAIN, "powf", x, 0, z);
+  if (x < 0 && y != floorf(y)) math_error(_DOMAIN, "powf", x, y, z);
+  else if (!x && finitef(y) && y < 0) math_error(_SING, "powf", x, y, z);
+  else if (finitef(x) && finitef(y) && !finitef(z)) math_error(_OVERFLOW, "powf", x, y, z);
+  else if (x && finitef(x) && finitef(y) && !z) math_error(_UNDERFLOW, "powf", x, y, z);
   return z;
 }
 
@@ -530,9 +532,11 @@ double CDECL MSVCRT_log10( double x )
  */
 double CDECL MSVCRT_pow( double x, double y )
 {
-  /* FIXME: If x < 0 and y is not integral, set EDOM */
   double z = pow(x,y);
-  if (!isfinite(z)) math_error(_DOMAIN, "pow", x, y, z);
+  if (x < 0 && y != floor(y)) math_error(_DOMAIN, "pow", x, y, z);
+  else if (!x && isfinite(y) && y < 0) math_error(_SING, "pow", x, y, z);
+  else if (isfinite(x) && isfinite(y) && !isfinite(z)) math_error(_OVERFLOW, "pow", x, y, z);
+  else if (x && isfinite(x) && isfinite(y) && !z) math_error(_UNDERFLOW, "pow", x, y, z);
   return z;
 }
 
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 04718c9..d17f2d0 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -647,6 +647,29 @@ static void test_math_errors(void)
         {"atan2", INFINITY, 0, -1, -1},
         {"atan2", 0, -INFINITY, -1, -1},
         {"atan2", 0, INFINITY, -1, -1},
+        {"pow", -INFINITY, -2, -1, -1},
+        {"pow", -INFINITY, -1, -1, -1},
+        {"pow", -INFINITY, 0, -1, -1},
+        {"pow", -INFINITY, 1, -1, -1},
+        {"pow", -INFINITY, 2, -1, -1},
+        {"pow", -1e100, -10, -1, _UNDERFLOW},
+        {"pow", -1e100, 10, ERANGE, _OVERFLOW},
+        {"pow", -1, 1.5, EDOM, _DOMAIN},
+        {"pow", 0, -2, ERANGE, _SING},
+        {"pow", 0, -1, ERANGE, _SING},
+        {"pow", 0.5, -INFINITY, -1, -1},
+        {"pow", 0.5, INFINITY, -1, -1},
+        {"pow", 2, -INFINITY, -1, -1},
+        {"pow", 2, -1e100, -1, _UNDERFLOW},
+        {"pow", 2, 1e100, ERANGE, _OVERFLOW},
+        {"pow", 2, INFINITY, -1, -1},
+        {"pow", 1e100, -10, -1, _UNDERFLOW},
+        {"pow", 1e100, 10, ERANGE, _OVERFLOW},
+        {"pow", INFINITY, -2, -1, -1},
+        {"pow", INFINITY, -1, -1, -1},
+        {"pow", INFINITY, 0, -1, -1},
+        {"pow", INFINITY, 1, -1, -1},
+        {"pow", INFINITY, 2, -1, -1},
     };
     const struct {
         char func[16];




More information about the wine-cvs mailing list