[BACK]Return to fma.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpfr

Annotation of OpenXM_contrib/gmp/mpfr/fma.c, Revision 1.1.1.1

1.1       ohara       1: /* mpfr_fma -- Floating multiply-add
                      2:
                      3: Copyright 2001, 2002 Free Software Foundation, Inc.
                      4:
                      5: This file is part of the MPFR Library.
                      6:
                      7: The MPFR Library is free software; you can redistribute
                      8: it and/or modify it under the terms of the GNU Lesser
                      9: General Public License as published by the Free Software
                     10: Foundation; either version 2.1 of the License, or (at your
                     11: option) any later version.
                     12:
                     13: The MPFR Library is distributed in the hope that it will
                     14: be useful, but WITHOUT ANY WARRANTY; without even the
                     15: implied warranty of MERCHANTABILITY or FITNESS FOR A
                     16: PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     17: License for more details.
                     18:
                     19: You should have received a copy of the GNU Lesser
                     20: General Public License along with the MPFR Library; see
                     21: the file COPYING.LIB.  If not, write to the Free Software
                     22: Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     23: MA 02111-1307, USA. */
                     24:
                     25: #include "gmp.h"
                     26: #include "gmp-impl.h"
                     27: #include "mpfr.h"
                     28: #include "mpfr-impl.h"
                     29:
                     30:
                     31: /* The computation of fma of x y and u is done by
                     32:     fma(s,x,y,z)= z + x*y = s
                     33: */
                     34:
                     35: int
                     36: mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
                     37:           mp_rnd_t rnd_mode)
                     38: {
                     39:   int inexact;
                     40:   mpfr_t u;
                     41:
                     42:   /* particular cases */
                     43:   if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
                     44:     {
                     45:       MPFR_SET_NAN(s);
                     46:       MPFR_RET_NAN;
                     47:     }
                     48:
                     49:   if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
                     50:     {
                     51:       /* cases Inf*0+z, 0*Inf+z, Inf-Inf */
                     52:       if ((MPFR_IS_FP(y) && MPFR_IS_ZERO(y)) ||
                     53:           (MPFR_IS_FP(x) && MPFR_IS_ZERO(x)) ||
                     54:           (MPFR_IS_INF(z) && ((MPFR_SIGN(x) * MPFR_SIGN(y)) != MPFR_SIGN(z))))
                     55:         {
                     56:           MPFR_SET_NAN(s);
                     57:           MPFR_RET_NAN;
                     58:         }
                     59:
                     60:       MPFR_CLEAR_NAN(s);
                     61:
                     62:       if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
                     63:         {
                     64:           MPFR_SET_INF(s);
                     65:           MPFR_SET_SAME_SIGN(s, z);
                     66:           MPFR_RET(0);
                     67:         }
                     68:       else /* z is finite */
                     69:         {
                     70:           MPFR_SET_INF(s);
                     71:           if (MPFR_SIGN(s) != (MPFR_SIGN(x) * MPFR_SIGN(y)))
                     72:             MPFR_CHANGE_SIGN(s);
                     73:           MPFR_RET(0);
                     74:         }
                     75:     }
                     76:
                     77:   MPFR_CLEAR_NAN(s);
                     78:
                     79:   /* now x and y are finite */
                     80:   if (MPFR_IS_INF(z))
                     81:     {
                     82:       MPFR_SET_INF(s);
                     83:       MPFR_SET_SAME_SIGN(s, z);
                     84:       MPFR_RET(0);
                     85:     }
                     86:
                     87:   MPFR_CLEAR_INF(s);
                     88:
                     89:   if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
                     90:     {
                     91:       if (MPFR_IS_ZERO(z))
                     92:         {
                     93:           int sign_p, sign_z;
                     94:           sign_p = MPFR_SIGN(x) * MPFR_SIGN(y);
                     95:           sign_z = MPFR_SIGN(z);
                     96:           if (MPFR_SIGN(s) !=
                     97:               (rnd_mode != GMP_RNDD ?
                     98:                ((sign_p < 0 && sign_z < 0) ? -1 : 1) :
                     99:                ((sign_p > 0 && sign_z > 0) ? 1 : -1)))
                    100:             {
                    101:               MPFR_CHANGE_SIGN(s);
                    102:             }
                    103:           MPFR_SET_ZERO(s);
                    104:           MPFR_RET(0);
                    105:         }
                    106:       else
                    107:         return mpfr_set (s, z, rnd_mode);
                    108:     }
                    109:
                    110:   if (MPFR_IS_ZERO(z))
                    111:     return mpfr_mul (s, x, y, rnd_mode);
                    112:
                    113:   /* if we take prec(u) >= prec(x) + prec(y), the product
                    114:      u <- x*y is always exact */
                    115:   mpfr_init2 (u, MPFR_PREC(x) + MPFR_PREC(y));
                    116:   mpfr_mul (u, x, y, GMP_RNDN); /* always exact */
                    117:   inexact = mpfr_add (s, z, u, rnd_mode);
                    118:   mpfr_clear(u);
                    119:
                    120:   return inexact;
                    121: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>