diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 05a2b72efd1..60ce4e659f5 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 04718c9e3d5..d17f2d08864 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];