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

Diff for /OpenXM_contrib/gmp/mpf/Attic/set_str.c between version 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2000/01/10 15:35:22 version 1.1.1.2, 2000/09/09 14:13:08
Line 2 
Line 2 
    in base BASE to a float in dest.  If BASE is zero, the leading characters     in base BASE to a float in dest.  If BASE is zero, the leading characters
    of STRING is used to figure out the base.     of STRING is used to figure out the base.
   
 Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.  Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000 Free Software Foundation,
   Inc.
   
 This file is part of the GNU MP Library.  This file is part of the GNU MP Library.
   
 The GNU MP Library is free software; you can redistribute it and/or modify  The GNU MP Library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Library General Public License as published by  it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your  the Free Software Foundation; either version 2.1 of the License, or (at your
 option) any later version.  option) any later version.
   
 The GNU MP Library is distributed in the hope that it will be useful, but  The GNU MP Library is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.  License for more details.
   
 You should have received a copy of the GNU Library General Public License  You should have received a copy of the GNU Lesser General Public License
 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to  along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,  the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 MA 02111-1307, USA. */  MA 02111-1307, USA. */
Line 27  MA 02111-1307, USA. */
Line 28  MA 02111-1307, USA. */
 #include "gmp-impl.h"  #include "gmp-impl.h"
 #include "longlong.h"  #include "longlong.h"
   
   
 long int strtol _PROTO ((const char *, char **ptr, int));  long int strtol _PROTO ((const char *, char **ptr, int));
   
 static int  static int
   #if __STDC__
   digit_value_in_base (int c, int base)
   #else
 digit_value_in_base (c, base)  digit_value_in_base (c, base)
      int c;       int c;
      int base;       int base;
   #endif
 {  {
   int digit;    int digit;
   
Line 89  mpf_set_str (x, str, base)
Line 95  mpf_set_str (x, str, base)
   decimal_exponent_flag = base < 0;    decimal_exponent_flag = base < 0;
   base = ABS (base);    base = ABS (base);
   
   if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)    if (digit_value_in_base (c, base == 0 ? 10 : base) < 0
         && (c != '.' || digit_value_in_base (str[1], base == 0 ? 10 : base) < 0))
     return -1;                  /* error if no digits */      return -1;                  /* error if no digits */
   
   /* If BASE is 0, try to find out the base by looking at the initial    /* If BASE is 0, try to find out the base by looking at the initial
Line 101  mpf_set_str (x, str, base)
Line 108  mpf_set_str (x, str, base)
       if (c == '0')        if (c == '0')
         {          {
           base = 8;            base = 8;
           c = *++str;            if (str[1] == 'x' || str[1] == 'X')
           if (c == 'x' || c == 'X')              {
             base = 16;                base = 16;
                 str += 2;
                 c = *str;
               }
         }          }
 #endif  #endif
     }      }
Line 159  mpf_set_str (x, str, base)
Line 169  mpf_set_str (x, str, base)
   xsize = str_size / __mp_bases[base].chars_per_limb + 2;    xsize = str_size / __mp_bases[base].chars_per_limb + 2;
   {    {
     long exp_in_base;      long exp_in_base;
     mp_size_t rsize, msize;      mp_size_t ralloc, rsize, msize;
     int cnt, i;      int cnt, i;
     mp_ptr mp, xp, tp, rp;      mp_ptr mp, tp, rp;
     mp_limb_t cy;  
     mp_exp_t exp_in_limbs;      mp_exp_t exp_in_limbs;
     mp_size_t prec = x->_mp_prec;      mp_size_t prec = x->_mp_prec + 1;
     int divflag;      int divflag;
     mp_size_t xxx = 0;      mp_size_t madj, radj;
   
     mp = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB);      mp = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB);
     msize = mpn_set_str (mp, (unsigned char *) begs, str_size, base);      msize = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
Line 179  mpf_set_str (x, str, base)
Line 188  mpf_set_str (x, str, base)
         return 0;          return 0;
       }        }
   
       madj = 0;
       /* Ignore excess limbs in MP,MSIZE.  */
       if (msize > prec)
         {
           madj = msize - prec;
           mp += msize - prec;
           msize = prec;
         }
   
     if (expflag != 0)      if (expflag != 0)
       exp_in_base = strtol (str + 1, (char **) 0,        exp_in_base = strtol (str + 1, (char **) 0,
                             decimal_exponent_flag ? 10 : base);                              decimal_exponent_flag ? 10 : base);
Line 193  mpf_set_str (x, str, base)
Line 211  mpf_set_str (x, str, base)
       {        {
         MPN_COPY (x->_mp_d, mp, msize);          MPN_COPY (x->_mp_d, mp, msize);
         x->_mp_size = negative ? -msize : msize;          x->_mp_size = negative ? -msize : msize;
         x->_mp_exp = msize;          x->_mp_exp = msize + madj;
         TMP_FREE (marker);          TMP_FREE (marker);
         return 0;          return 0;
       }        }
   
 #if 1      radj = 0;                   /* counts number of ignored low limbs in r */
     rsize = (((mp_size_t) (exp_in_base / __mp_bases[base].chars_per_bit_exactly))  
              / BITS_PER_MP_LIMB + 3);  
 #else  
     count_leading_zeros (cnt, (mp_limb_t) base);  
     rsize = exp_in_base - cnt * exp_in_base / BITS_PER_MP_LIMB + 1;  
 #endif  
     rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);  
     tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);  
   
       ralloc = 2 * (prec + 1);
       rp = (mp_ptr) TMP_ALLOC (ralloc * BYTES_PER_MP_LIMB);
       tp = (mp_ptr) TMP_ALLOC (ralloc * BYTES_PER_MP_LIMB);
   
     rp[0] = base;      rp[0] = base;
     rsize = 1;      rsize = 1;
   
     count_leading_zeros (cnt, exp_in_base);      count_leading_zeros (cnt, exp_in_base);
   
     for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)      for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
       {        {
         mpn_mul_n (tp, rp, rp, rsize);          mpn_mul_n (tp, rp, rp, rsize);
         rsize = 2 * rsize;          rsize = 2 * rsize;
         rsize -= tp[rsize - 1] == 0;          rsize -= tp[rsize - 1] == 0;
         xp = tp; tp = rp; rp = xp;          radj <<= 1;
   
           if (rsize > prec)
             {
               radj += rsize - prec;
               MPN_COPY_INCR (rp, tp + rsize - prec, prec);
               rsize = prec;
             }
           else
             MP_PTR_SWAP (rp, tp);
   
         if (((exp_in_base >> i) & 1) != 0)          if (((exp_in_base >> i) & 1) != 0)
           {            {
               mp_limb_t cy;
             cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);              cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
             rp[rsize] = cy;              rp[rsize] = cy;
             rsize += cy != 0;              rsize += cy != 0;
Line 230  mpf_set_str (x, str, base)
Line 252  mpf_set_str (x, str, base)
   
     if (rsize > prec)      if (rsize > prec)
       {        {
         xxx += rsize - prec;          radj += rsize - prec;
         rp += rsize - prec;          rp += rsize - prec;
         rsize = prec;          rsize = prec;
       }        }
 #if 0  
     if (msize > prec)  
       {  
         xxx -= msize - prec;  
         mp += msize - prec;  
         msize = prec;  
       }  
 #endif  
     if (divflag)      if (divflag)
       {        {
         mp_ptr qp;          mp_ptr qp;
         mp_limb_t qflag;          mp_limb_t qlimb;
         mp_size_t xtra;          if (msize < rsize)
         if (msize <= rsize)  
           {            {
             /* Allocate extra limb for current divrem sematics. */              /* Pad out MP,MSIZE for current divrem semantics.  */
             mp_ptr tmp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);              mp_ptr tmp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
             MPN_ZERO (tmp, rsize - msize);              MPN_ZERO (tmp, rsize - msize);
             MPN_COPY (tmp + rsize - msize, mp, msize);              MPN_COPY (tmp + rsize - msize, mp, msize);
             mp = tmp;              mp = tmp;
             xxx += rsize - msize;              madj -= rsize - msize;
             msize = rsize;              msize = rsize;
           }            }
         count_leading_zeros (cnt, rp[rsize - 1]);          count_leading_zeros (cnt, rp[rsize - 1]);
         if (cnt != 0)          if (cnt != 0)
           {            {
               mp_limb_t cy;
             mpn_lshift (rp, rp, rsize, cnt);              mpn_lshift (rp, rp, rsize, cnt);
             cy = mpn_lshift (mp, mp, msize, cnt);              cy = mpn_lshift (mp, mp, msize, cnt);
             if (cy)              if (cy)
               mp[msize++] = cy;                mp[msize++] = cy;
           }            }
   
         qp = (mp_ptr) TMP_ALLOC ((prec + 1) * BYTES_PER_MP_LIMB);          qp = (mp_ptr) TMP_ALLOC ((prec + 1) * BYTES_PER_MP_LIMB);
         xtra = prec - (msize - rsize);          qlimb = mpn_divrem (qp, prec - (msize - rsize), mp, msize, rp, rsize);
         qflag = mpn_divrem (qp, xtra, mp, msize, rp, rsize);  
         qp[prec] = qflag;  
         tp = qp;          tp = qp;
         rsize = prec + qflag;          exp_in_limbs = qlimb + (msize - rsize) + (madj - radj);
         exp_in_limbs = rsize - xtra - xxx;          rsize = prec;
           if (qlimb != 0)
             {
               tp[prec] = qlimb;
               /* Skip the least significant limb not to overrun the destination
                  variable.  */
               tp++;
             }
       }        }
     else      else
       {        {
Line 282  mpf_set_str (x, str, base)
Line 303  mpf_set_str (x, str, base)
           mpn_mul (tp, mp, msize, rp, rsize);            mpn_mul (tp, mp, msize, rp, rsize);
         rsize += msize;          rsize += msize;
         rsize -= tp[rsize - 1] == 0;          rsize -= tp[rsize - 1] == 0;
         exp_in_limbs = rsize + xxx;          exp_in_limbs = rsize + madj + radj;
   
         if (rsize > prec)          if (rsize > prec)
           {            {
             xxx = rsize - prec;  
             tp += rsize - prec;              tp += rsize - prec;
             rsize = prec;              rsize = prec;
             exp_in_limbs += 0;              exp_in_limbs += 0;

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2

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