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

Annotation of OpenXM_contrib/gmp/mpfr/div.c, Revision 1.1.1.2

1.1       maekawa     1: /* mpfr_div -- divide two floating-point numbers
                      2:
1.1.1.2 ! ohara       3: Copyright 1999, 2001 Free Software Foundation.
1.1       maekawa     4:
                      5: This file is part of the MPFR Library.
                      6:
                      7: The MPFR Library is free software; you can redistribute it and/or modify
1.1.1.2 ! ohara       8: it under the terms of the GNU Lesser General Public License as published by
        !             9: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1       maekawa    10: option) any later version.
                     11:
                     12: The MPFR Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 ! ohara      14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
1.1       maekawa    15: License for more details.
                     16:
1.1.1.2 ! ohara      17: You should have received a copy of the GNU Lesser General Public License
1.1       maekawa    18: along with the MPFR Library; see the file COPYING.LIB.  If not, write to
                     19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20: MA 02111-1307, USA. */
                     21:
                     22: #include "gmp.h"
                     23: #include "gmp-impl.h"
                     24: #include "longlong.h"
1.1.1.2 ! ohara      25: #include "mpfr.h"
        !            26: #include "mpfr-impl.h"
1.1       maekawa    27:
1.1.1.2 ! ohara      28: int
        !            29: mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mp_rnd_t rnd_mode)
1.1       maekawa    30: {
1.1.1.2 ! ohara      31:   mp_srcptr up, vp, bp;
        !            32:   mp_size_t usize, vsize;
        !            33:
        !            34:   mp_ptr ap, qp, rp;
        !            35:   mp_size_t asize, bsize, qsize, rsize;
        !            36:   mp_exp_t qexp;
        !            37:
        !            38:   mp_rnd_t rnd_mode1, rnd_mode2;
        !            39:
        !            40:   mp_size_t err, k;
        !            41:   mp_limb_t near;
        !            42:   int inex, sh, can_round, can_round2, sign_quotient;
        !            43:   unsigned int cc = 0, rw;
        !            44:
1.1       maekawa    45:   TMP_DECL (marker);
                     46:
                     47:
1.1.1.2 ! ohara      48:   /**************************************************************************
        !            49:    *                                                                        *
        !            50:    *              This part of the code deals with special cases            *
        !            51:    *                                                                        *
        !            52:    **************************************************************************/
1.1       maekawa    53:
1.1.1.2 ! ohara      54:   if (MPFR_IS_NAN(u) || MPFR_IS_NAN(v))
1.1       maekawa    55:     {
1.1.1.2 ! ohara      56:       MPFR_SET_NAN(q);
        !            57:       MPFR_RET_NAN;
1.1       maekawa    58:     }
                     59:
1.1.1.2 ! ohara      60:   MPFR_CLEAR_NAN(q);
1.1       maekawa    61:
1.1.1.2 ! ohara      62:   sign_quotient = MPFR_SIGN(u) * MPFR_SIGN(v);
        !            63:   if (MPFR_SIGN(q) != sign_quotient)
        !            64:     MPFR_CHANGE_SIGN(q);
1.1       maekawa    65:
1.1.1.2 ! ohara      66:   if (MPFR_IS_INF(u))
1.1       maekawa    67:     {
1.1.1.2 ! ohara      68:       if (MPFR_IS_INF(v))
        !            69:        {
        !            70:          MPFR_SET_NAN(q);
        !            71:           MPFR_RET_NAN;
        !            72:        }
        !            73:       else
        !            74:        {
        !            75:           MPFR_SET_INF(q);
        !            76:           MPFR_RET(0);
        !            77:        }
1.1       maekawa    78:     }
1.1.1.2 ! ohara      79:   else
        !            80:     if (MPFR_IS_INF(v))
        !            81:       {
        !            82:         MPFR_CLEAR_INF(q);
        !            83:         MPFR_SET_ZERO(q);
        !            84:         MPFR_RET(0);
        !            85:       }
1.1       maekawa    86:
1.1.1.2 ! ohara      87:   MPFR_CLEAR_INF(q); /* clear Inf flag */
1.1       maekawa    88:
1.1.1.2 ! ohara      89:   if (MPFR_IS_ZERO(v))
        !            90:     {
        !            91:       if (MPFR_IS_ZERO(u))
        !            92:        {
        !            93:           MPFR_SET_NAN(q);
        !            94:           MPFR_RET_NAN;
        !            95:        }
        !            96:       else
        !            97:        {
        !            98:           MPFR_SET_INF(q);
        !            99:           MPFR_RET(0);
        !           100:        }
        !           101:     }
1.1       maekawa   102:
1.1.1.2 ! ohara     103:   if (MPFR_IS_ZERO(u))
1.1       maekawa   104:     {
1.1.1.2 ! ohara     105:       MPFR_SET_ZERO(q);
        !           106:       MPFR_RET(0);
        !           107:     }
1.1       maekawa   108:
1.1.1.2 ! ohara     109:   /**************************************************************************
        !           110:    *                                                                        *
        !           111:    *              End of the part concerning special values.                *
        !           112:    *                                                                        *
        !           113:    **************************************************************************/
        !           114:
        !           115:
        !           116:   up = MPFR_MANT(u);
        !           117:   vp = MPFR_MANT(v);
        !           118:
        !           119:   TMP_MARK (marker);
        !           120:   usize = MPFR_ESIZE(u);
        !           121:   vsize = MPFR_ESIZE(v);
        !           122:
        !           123:   /**************************************************************************
        !           124:    *                                                                        *
        !           125:    *   First try to use only part of u, v. If this is not sufficient,       *
        !           126:    *   use the full u and v, to avoid long computations eg. in the case     *
        !           127:    *   u = v.                                                               *
        !           128:    *                                                                        *
        !           129:    **************************************************************************/
1.1       maekawa   130:
1.1.1.2 ! ohara     131:   /* The dividend is a, length asize. The divisor is b, length bsize. */
1.1       maekawa   132:
1.1.1.2 ! ohara     133:   qsize = (MPFR_PREC(q) + 3)/BITS_PER_MP_LIMB + 1;
        !           134:   if (vsize < qsize)
        !           135:     {
        !           136:       bsize = vsize;
        !           137:       bp = vp;
        !           138:     }
        !           139:   else
        !           140:     {
        !           141:       bsize = qsize;
        !           142:       bp = (mp_srcptr)vp + vsize - qsize;
        !           143:     }
        !           144:
        !           145:   asize = bsize + qsize;
        !           146:   ap = (mp_ptr) TMP_ALLOC(asize * BYTES_PER_MP_LIMB);
        !           147:   if (asize > usize)
        !           148:     {
        !           149:       MPN_COPY(ap + asize - usize, up, usize);
        !           150:       MPN_ZERO(ap, asize - usize);
        !           151:     }
        !           152:   else
        !           153:     MPN_COPY(ap, up + usize - asize, asize);
        !           154:
        !           155:   /* Allocate limbs for quotient and remainder. */
        !           156:   qp = (mp_ptr) TMP_ALLOC ((qsize + 1) * BYTES_PER_MP_LIMB);
        !           157:   rp = (mp_ptr) TMP_ALLOC (bsize * BYTES_PER_MP_LIMB);
        !           158:   rsize = bsize;
1.1       maekawa   159:
1.1.1.2 ! ohara     160:   mpn_tdiv_qr(qp, rp, 0, ap, asize, bp, bsize);
        !           161:
        !           162:   /* Estimate number of correct bits. */
        !           163:
        !           164:   err = qsize * BITS_PER_MP_LIMB;
        !           165:   if (bsize < vsize) err -= 2; else if (asize < usize) err --;
        !           166:
        !           167:   /* We want to check if rounding is possible, but without normalizing
        !           168:      because we might have to divide again if rounding is impossible, or
        !           169:      if the result might be exact. We have however to mimic normalization */
        !           170:
        !           171:   if (qp[qsize] != 0) { sh = -1; }
        !           172:   else { count_leading_zeros(sh, qp[qsize - 1]); }
        !           173:
        !           174:   /*
        !           175:      To detect asap if the result is inexact, so as to avoid doing the
        !           176:      division completely, we perform the following check :
        !           177:
        !           178:      - if rnd_mode == GMP_RNDN, and the result is exact, we are unable
        !           179:      to round simultaneously to zero and to infinity ;
        !           180:
        !           181:      - if rnd_mode == GMP_RNDN, and if we can round to zero with one extra
        !           182:      bit of precision, we can decide rounding. Hence in that case, check
        !           183:      as in the case of GMP_RNDN, with one extra bit. Note that in the case
        !           184:      of close to even rounding we shall do the division completely, but
        !           185:      this is necessary anyway : we need to know whether this is really
        !           186:      even rounding or not.
        !           187:   */
        !           188:
        !           189:   if (rnd_mode == GMP_RNDN)
        !           190:     {
        !           191:       rnd_mode1 = GMP_RNDZ;
        !           192:       near = 1;
        !           193:     }
        !           194:   else
        !           195:     {
        !           196:       rnd_mode1 = rnd_mode;
        !           197:       near = 0;
        !           198:     }
        !           199:
        !           200:   sh += near;
        !           201:   can_round = mpfr_can_round_raw(qp, qsize + 1, sign_quotient, err + sh +
        !           202:                                 BITS_PER_MP_LIMB, GMP_RNDN, rnd_mode1,
        !           203:                                 MPFR_PREC(q) + sh + BITS_PER_MP_LIMB);
        !           204:
        !           205:   switch (rnd_mode1)
        !           206:     {
        !           207:     case GMP_RNDU : rnd_mode2 = GMP_RNDD; break;
        !           208:     case GMP_RNDD : rnd_mode2 = GMP_RNDU; break;
        !           209:     case GMP_RNDZ : rnd_mode2 = sign_quotient == 1 ? GMP_RNDU : GMP_RNDD;
        !           210:       break;
        !           211:     default : rnd_mode2 = GMP_RNDZ;
        !           212:     }
        !           213:
        !           214:   can_round2 = mpfr_can_round_raw(qp, qsize + 1, sign_quotient, err + sh +
        !           215:                                  BITS_PER_MP_LIMB, GMP_RNDN, rnd_mode2,
        !           216:                                  MPFR_PREC(q) + sh + BITS_PER_MP_LIMB);
        !           217:
        !           218:   sh -= near;
        !           219:
        !           220:   /* If either can_round or can_round2 is 0, either we cannot round or
        !           221:      the result might be exact. If asize >= usize and bsize >= vsize, we
        !           222:      can just check this by looking at the remainder. Otherwise, we
        !           223:      have to correct our first approximation. */
        !           224:
        !           225:   if ((!can_round || !can_round2) && (asize < usize || bsize < vsize))
        !           226:     {
        !           227:       int b = 0;
        !           228:       mp_ptr rem, rem2;
        !           229:
        !           230:   /**************************************************************************
        !           231:    *                                                                        *
        !           232:    *   The attempt to use only part of u and v failed. We first compute a   *
        !           233:    *   correcting term, then perform the full division.                     *
        !           234:    *   Put u = uhi + ulo, v = vhi + vlo. We have uhi = vhi * qp + rp,       *
        !           235:    *   thus u - qp * v = rp + ulo - qp * vlo, that we shall divide by v.    *
        !           236:    *                                                                        *
        !           237:    **************************************************************************/
        !           238:
        !           239:       rsize = qsize + 1 +
        !           240:              (usize - asize > vsize - bsize
        !           241:               ? usize - asize
        !           242:               : vsize - bsize);
        !           243:
        !           244:       /*
        !           245:        TODO : One operand is probably enough, but then we have to
        !           246:        perform one further comparison (compute first vlo * q,
        !           247:        try to substract r, try to substract ulo. Which is best ?
        !           248:        NB : ulo and r do not overlap. Draw advantage of this
        !           249:        [eg. HI(vlo*q) = r => compare LO(vlo*q) with b.]
        !           250:       */
        !           251:
        !           252:       rem = TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
        !           253:       rem2 = TMP_ALLOC(rsize * BYTES_PER_MP_LIMB);
        !           254:
        !           255:       rem[rsize - 1] = rem2 [rsize - 1] = 0;
        !           256:
        !           257:       if (bsize < vsize)
        !           258:        {
        !           259:          /* Compute vlo * q */
        !           260:          if (qsize + 1 > vsize - bsize)
        !           261:            mpn_mul(rem + rsize - vsize - qsize - 1 + bsize,
        !           262:                    qp, qsize + 1, vp, vsize - bsize);
        !           263:          else
        !           264:            mpn_mul(rem + rsize - vsize - qsize - 1 + bsize,
        !           265:                    vp, vsize - bsize, qp, qsize + 1);
        !           266:
        !           267:          MPN_ZERO(rem, rsize - vsize - qsize - 1 + bsize);
        !           268:        }
        !           269:       else MPN_ZERO(rem, rsize);
        !           270:
        !           271:       /* Compute ulo + r. The two of them do not overlap. */
        !           272:       MPN_COPY(rem2 + rsize - 1 - qsize, rp, bsize);
1.1       maekawa   273:
1.1.1.2 ! ohara     274:       if (qsize + 1 > bsize)
        !           275:        MPN_ZERO(rem2 + rsize - 1 - qsize + bsize, qsize + 1 - bsize);
        !           276:
        !           277:       if (asize < usize)
1.1       maekawa   278:        {
1.1.1.2 ! ohara     279:          MPN_COPY(rem2 + rsize - 1 - qsize - usize + asize,
        !           280:                   up, usize - asize);
        !           281:          MPN_ZERO(rem2, rsize - 1 - qsize - usize + asize);
1.1       maekawa   282:        }
1.1.1.2 ! ohara     283:       else
        !           284:        MPN_ZERO(rem2, rsize - 1 - qsize);
        !           285:
        !           286:       b = 0;
        !           287:       if (mpn_cmp(rem2, rem, rsize) >= 0)
        !           288:        {
        !           289:          /* Positive correction is at most 1. */
        !           290:
        !           291:          mpn_sub_n(rem, rem2, rem, rsize);
        !           292:          if (rem[rsize - 1] != 0 ||
        !           293:              mpn_cmp(rem + rsize - vsize - 1, vp, vsize) >= 0)
        !           294:            {
        !           295:              rem[rsize - 1] -=
        !           296:                mpn_sub_n(rem + rsize - vsize - 1,
        !           297:                          rem + rsize - vsize - 1,
        !           298:                          vp, vsize);
        !           299:              qp[qsize] -= mpn_add_1(qp, qp, qsize, 1);
        !           300:            }
        !           301:        }
        !           302:       else
1.1       maekawa   303:        {
1.1.1.2 ! ohara     304:          /* Negative correction is at most 3 */
        !           305:          do
        !           306:            {
        !           307:              b++;
        !           308:              rem2[rsize - 1] +=
        !           309:                mpn_add_n(rem2 + rsize - vsize - 1,
        !           310:                          rem2 + rsize - vsize - 1, vp, vsize);
        !           311:            }
        !           312:          while (mpn_cmp(rem2, rem, rsize) < 0);
        !           313:
        !           314:          qp[qsize] -= mpn_sub_1(qp, qp, qsize, b);
        !           315:          mpn_sub_n(rem, rem2, rem, rsize);
1.1       maekawa   316:        }
1.1.1.2 ! ohara     317:
        !           318:       if (qp[qsize] != 0)
        !           319:        sh = -1;
        !           320:       else
        !           321:        count_leading_zeros(sh, qp[qsize - 1]);
1.1       maekawa   322:
1.1.1.2 ! ohara     323:       err = BITS_PER_MP_LIMB * qsize;
        !           324:       rp = rem;
        !           325:     }
        !           326:
        !           327:   /**************************************************************************
        !           328:    *                                                                        *
        !           329:    *                       Final stuff (rounding and so.)                   *
        !           330:    *  From now on : qp is the quotient [size qsize], rp the remainder       *
        !           331:    *  [size rsize].                                                         *
        !           332:    **************************************************************************/
1.1       maekawa   333:
1.1.1.2 ! ohara     334:   qexp = MPFR_EXP(u) - MPFR_EXP(v);
1.1       maekawa   335:
1.1.1.2 ! ohara     336:   if (qp[qsize] != 0)
        !           337:     /* Hack : qp[qsize] is 0, 1 or 2, hence if not 0, = 2^(qp[qsize] - 1). */
        !           338:     {
        !           339:       near = mpn_rshift(qp, qp, qsize, qp[qsize]);
        !           340:       qp[qsize - 1] |= GMP_LIMB_HIGHBIT; qexp += qp[qsize];
        !           341:     }
        !           342:   else
        !           343:     {
        !           344:       near = 0;
        !           345:       if (sh != 0)
1.1       maekawa   346:        {
1.1.1.2 ! ohara     347:          mpn_lshift(qp, qp, qsize, sh);
        !           348:          qexp -= sh;
1.1       maekawa   349:        }
                    350:     }
1.1.1.2 ! ohara     351:
        !           352:   cc = mpfr_round_raw_generic(qp, qp, err, (sign_quotient == -1 ? 1 : 0),
        !           353:                              MPFR_PREC(q), rnd_mode, &inex, 1);
1.1       maekawa   354:
1.1.1.2 ! ohara     355:   qp += qsize - MPFR_ESIZE(q); /* 0 or 1 */
        !           356:   qsize = MPFR_ESIZE(q);
        !           357:
        !           358:   /*
        !           359:      At that point, either we were able to round from the beginning,
        !           360:      and know thus that the result is inexact.
        !           361:
        !           362:      Or we have performed a full division. In that case, we might still
        !           363:      be wrong if both
        !           364:      - the remainder is nonzero ;
        !           365:      - we are rounding to infinity or to nearest (the nasty case of even
        !           366:      rounding).
        !           367:      - inex = 0, meaning that the non-significant bits of the quotients are 0,
        !           368:      except when rounding to nearest (the nasty case of even rounding again).
        !           369:   */
        !           370:
        !           371:   if (!can_round || !can_round2) /* Lazy case. */
1.1       maekawa   372:     {
1.1.1.2 ! ohara     373:       if (inex == 0)
        !           374:        {
        !           375:          k = rsize - 1;
        !           376:
        !           377:          /* If a bit has been shifted out during normalization, hence
        !           378:             the remainder is nonzero. */
        !           379:          if (near == 0)
        !           380:            while (k >= 0) { if (rp[k]) break; k--; }
        !           381:
        !           382:          if (k >= 0) /* Remainder is nonzero. */
1.1       maekawa   383:            {
1.1.1.2 ! ohara     384:              if ((rnd_mode == GMP_RNDD && sign_quotient == -1)
        !           385:                  || (rnd_mode == GMP_RNDU && sign_quotient == 1))
        !           386:                /* Rounding to infinity. */
1.1       maekawa   387:                {
1.1.1.2 ! ohara     388:                  inex = sign_quotient;
        !           389:                  cc = 1;
1.1       maekawa   390:                }
1.1.1.2 ! ohara     391:              /* rounding to zero. */
        !           392:              else inex = -sign_quotient;
1.1       maekawa   393:            }
1.1.1.2 ! ohara     394:        }
        !           395:       else /* We might have to correct an even rounding if remainder
        !           396:              is nonzero and if even rounding was towards 0. */
        !           397:        if (rnd_mode == GMP_RNDN && (inex == MPFR_EVEN_INEX
        !           398:                                     || inex == -MPFR_EVEN_INEX))
        !           399:          {
        !           400:            k = rsize - 1;
        !           401:
        !           402:          /* If a bit has been shifted out during normalization, hence
        !           403:             the remainder is nonzero. */
        !           404:            if (near == 0)
        !           405:              while (k >= 0)
        !           406:                {
        !           407:                  if (rp[k])
        !           408:                    break;
        !           409:                  k--;
        !           410:                }
        !           411:
        !           412:            if (k >= 0) /* In fact the quotient is larger than expected */
        !           413:              {
        !           414:                inex = sign_quotient; /* To infinity, finally. */
        !           415:                cc = 1;
        !           416:              }
        !           417:          }
        !           418:     }
        !           419:
        !           420:   /* Final modification due to rounding */
        !           421:   if (cc)
        !           422:     {
        !           423:       sh = MPFR_PREC(q) & (BITS_PER_MP_LIMB - 1);
        !           424:       if (sh)
        !           425:        cc = mpn_add_1 (qp, qp, qsize,
        !           426:                         MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - sh));
        !           427:       else
        !           428:        cc = mpn_add_1 (qp, qp, qsize, MP_LIMB_T_ONE);
1.1       maekawa   429:
1.1.1.2 ! ohara     430:       if (cc)
        !           431:         {
        !           432:           mpn_rshift (qp, qp, qsize, 1);
        !           433:           qp[qsize-1] |= GMP_LIMB_HIGHBIT;
        !           434:           qexp++;
        !           435:         }
        !           436:     }
1.1       maekawa   437:
1.1.1.2 ! ohara     438:   rw = qsize * BITS_PER_MP_LIMB - MPFR_PREC(q);
        !           439:   MPN_COPY(MPFR_MANT(q), qp, qsize);
1.1       maekawa   440:   TMP_FREE (marker);
1.1.1.2 ! ohara     441:
        !           442:   MPFR_MANT(q)[0] &= ~((MP_LIMB_T_ONE << rw) - MP_LIMB_T_ONE);
        !           443:   MPFR_EXP(q) = qexp;
        !           444:
        !           445:   MPFR_RET(inex);
1.1       maekawa   446: }

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