* libm/mathfp/s_pow.c (pow): Fix checks on variable k. Add

exponent_is_even_int variable.  Handle case where x is
	negative, and y is an odd integer.
	* libm/mathfp/sf_pow.c (powf): Likewise.
This commit is contained in:
Thomas Fitzsimmons 2002-06-27 20:41:49 +00:00
parent c36e6dd754
commit 54be629f41
3 changed files with 90 additions and 51 deletions

View File

@ -1,5 +1,10 @@
2002-06-27 Thomas Fitzsimmons <fitzsim@redhat.com>
* libm/mathfp/s_pow.c (pow): Fix checks on variable k. Add
exponent_is_even_int variable. Handle case where x is
negative, and y is an odd integer.
* libm/mathfp/sf_pow.c (powf): Likewise.
* libm/mathfp/er_lgamma.c: Remove __kernel references.
* libm/mathfp/erf_lgamma.c: Likewise.
* libm/mathfp/s_tgamma.c: Likewise.

View File

@ -52,57 +52,67 @@ PORTABILITY
double pow (double x, double y)
{
double d, t, r = 1.0;
int n, k, sign = 0;
double d, k, t, r = 1.0;
int n, sign, exponent_is_even_int = 0;
__uint32_t px;
GET_HIGH_WORD (px, x);
k = modf (y, &d);
if (k == 0.0)
if (k == 0.0)
{
/* Exponent y is an integer. */
if (modf (ldexp (y, -1), &t))
sign = 0;
{
/* y is odd. */
exponent_is_even_int = 0;
}
else
sign = 1;
{
/* y is even. */
exponent_is_even_int = 1;
}
}
if (x == 0.0 && y <= 0.0)
errno = EDOM;
if (x == 0.0 && y <= 0.0)
{
errno = EDOM;
}
else if ((t = y * log (fabs (x))) >= BIGX)
{
errno = ERANGE;
if (px & 0x80000000)
{
if (!k)
/* x is negative. */
if (k)
{
/* y is not an integer. */
errno = EDOM;
x = 0.0;
}
else if (sign)
x = -z_infinity.d;
else if (exponent_is_even_int)
x = z_infinity.d;
else
x = z_infinity.d;
x = -z_infinity.d;
}
else
x = z_infinity.d;
}
else
{
x = z_infinity.d;
}
}
else if (t < SMALLX)
{
errno = ERANGE;
x = 0.0;
}
else
{
if ( k && fabs(d) <= 32767 )
if ( !k && fabs(d) <= 32767 )
{
n = (int) d;
if (sign = (n < 0))
if ((sign = (n < 0)))
n = -n;
while ( n > 0 )
@ -118,13 +128,14 @@ double pow (double x, double y)
return r;
}
else
{
if ( px & 0x80000000 )
{
if ( !k )
/* x is negative. */
if ( k )
{
/* y is not an integer. */
errno = EDOM;
return 0.0;
}
@ -132,13 +143,19 @@ double pow (double x, double y)
x = exp (t);
if ( sign )
{
px ^= 0x80000000;
SET_HIGH_WORD (x, px);
if (!exponent_is_even_int)
{
if (px & 0x80000000)
{
/* y is an odd integer, and x is negative,
so the result is negative. */
GET_HIGH_WORD (px, x);
px |= 0x80000000;
SET_HIGH_WORD (x, px);
}
}
}
}
}
return x;
}

View File

@ -7,56 +7,66 @@
float powf (float x, float y)
{
float d, t, r = 1.0;
int n, k, sign = 0;
int n, k, sign = 0, exponent_is_even_int = 0;
__int32_t px;
GET_FLOAT_WORD (px, x);
k = modff (y, &d);
if (k == 0.0)
{
/* Exponent y is an integer. */
if (modff (ldexpf (y, -1), &t))
sign = 0;
{
/* y is odd. */
exponent_is_even_int = 0;
}
else
sign = 1;
{
/* y is even. */
exponent_is_even_int = 1;
}
}
if (x == 0.0 && y <= 0.0)
errno = EDOM;
if (x == 0.0 && y <= 0.0)
{
errno = EDOM;
}
else if ((t = y * log (fabsf (x))) >= BIGX)
{
errno = ERANGE;
if (px & 0x80000000)
{
if (!k)
/* x is negative. */
if (k)
{
/* y is not an integer. */
errno = EDOM;
x = 0.0;
}
else if (sign)
x = -z_infinity_f.f;
else if (exponent_is_even_int)
x = z_infinity_f.f;
else
x = z_infinity_f.f;
x = -z_infinity_f.f;
}
else
x = z_infinity_f.f;
}
else
{
x = z_infinity_f.f;
}
}
else if (t < SMALLX)
{
errno = ERANGE;
x = 0.0;
}
else
{
if ( k && fabsf (d) <= 32767 )
if ( !k && fabsf (d) <= 32767 )
{
n = (int) d;
if (sign = (n < 0))
if ((sign = (n < 0)))
n = -n;
while ( n > 0 )
@ -72,13 +82,14 @@ float powf (float x, float y)
return r;
}
else
{
if ( px & 0x80000000 )
{
if ( !k )
/* x is negative. */
if (k)
{
/* y is not an integer. */
errno = EDOM;
return 0.0;
}
@ -86,13 +97,19 @@ float powf (float x, float y)
x = exp (t);
if ( sign )
if (!exponent_is_even_int)
{
px ^= 0x80000000;
SET_FLOAT_WORD (x, px);
if (px & 0x80000000)
{
/* y is an odd integer, and x is negative,
so the result is negative. */
GET_FLOAT_WORD (px, x);
px |= 0x80000000;
SET_FLOAT_WORD (x, px);
}
}
}
}
}
return x;
}