summaryrefslogtreecommitdiff
path: root/pow.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-16 13:35:20 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-16 13:35:20 +0000
commit57fcaf09d4bc7c07ac491b4bcb1b742c0aeea913 (patch)
tree3ffbfd8038a9db6aa1952307aba6f1116ac913ce /pow.c
parentaa00331925accdce43fa4da7a0262792c3ef1ea5 (diff)
downloadmpfr-57fcaf09d4bc7c07ac491b4bcb1b742c0aeea913.tar.gz
changed back to C99 standard for special values of x^y
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2721 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'pow.c')
-rw-r--r--pow.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/pow.c b/pow.c
index 9142497da..60311b320 100644
--- a/pow.c
+++ b/pow.c
@@ -140,7 +140,7 @@ is_odd (mpfr_srcptr y)
/* The computation of z = pow(x,y) is done by
z = exp(y * log(x)) = x^y
- For the special cases, see Section F.9.4.4 of the C standard:
+ For the special cases, see Section F.9.4.4 of the C99 standard:
_ pow(±0, y) = ±inf for y an odd integer < 0.
_ pow(±0, y) = +inf for y < 0 and not an odd integer.
_ pow(±0, y) = ±0 for y an odd integer > 0.
@@ -226,37 +226,33 @@ mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
}
}
}
- /* x is Inf or zero, and y is now an ordinary number (even non-zero) */
+ /* x is Inf or zero, and y is now an ordinary number (non-zero) */
MPFR_ASSERTD(MPFR_IS_FP(y));
if (MPFR_IS_INF(x))
{
/* +Inf^y gives +Inf if y > 0, +0 if y < 0
- -Inf^y gives NaN for y non-integer
- s*Inf for y positive integer of sign s
- s*0 for y negative integer of sign s */
+ -Inf^y gives -Inf for y an odd integer > 0 (a)
+ +Inf for y > 0 and not an odd integer (b)
+ -0 for y an odd integer < 0 (c)
+ +0 for y < 0 and not an odd integer (d).
+ Warning: these are the rules of the C99 standard, which
+ may be counter-intuitive, especially (b) and (d), where
+ we might expect NaN when taking the limit of x^y when x -> -Inf.
+ */
int negative;
/* Determine the sign now, in case y and z are the same object */
negative = MPFR_IS_NEG(x);
MPFR_CLEAR_FLAGS(z);
if (negative) /* x = -Inf */
{
- int odd = is_odd (y);
- if (odd == 0) /* non-integer */
- {
- MPFR_SET_NAN(z);
- MPFR_RET_NAN;
- }
- else
- {
- if (MPFR_IS_POS(y))
- MPFR_SET_INF(z);
- else
- MPFR_SET_ZERO(z);
- if (odd == 1) /* odd integer */
- MPFR_SET_NEG(z);
- else
- MPFR_SET_POS(z);
- }
+ if (MPFR_IS_POS(y))
+ MPFR_SET_INF(z);
+ else
+ MPFR_SET_ZERO(z);
+ if (is_odd (y) == 1) /* y is an odd integer */
+ MPFR_SET_NEG(z);
+ else
+ MPFR_SET_POS(z);
}
else /* x = +Inf */
{