[BACK]Return to extract-dbl.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

Annotation of OpenXM_contrib/gmp/extract-dbl.c, Revision 1.1.1.1

1.1       maekawa     1: /* __gmp_extract_double -- convert from double to array of mp_limb_t.
                      2:
                      3: Copyright (C) 1996, 1999, 2000 Free Software Foundation, Inc.
                      4:
                      5: This file is part of the GNU MP Library.
                      6:
                      7: The GNU MP Library is free software; you can redistribute it and/or modify
                      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
                     10: option) any later version.
                     11:
                     12: The GNU MP Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     15: License for more details.
                     16:
                     17: You should have received a copy of the GNU Lesser General Public License
                     18: along with the GNU MP 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:
                     25: #ifdef XDEBUG
                     26: #undef _GMP_IEEE_FLOATS
                     27: #endif
                     28:
                     29: #ifndef _GMP_IEEE_FLOATS
                     30: #define _GMP_IEEE_FLOATS 0
                     31: #endif
                     32:
                     33: /* Extract a non-negative double in d.  */
                     34:
                     35: int
                     36: #if __STDC__
                     37: __gmp_extract_double (mp_ptr rp, double d)
                     38: #else
                     39: __gmp_extract_double (rp, d)
                     40:      mp_ptr rp;
                     41:      double d;
                     42: #endif
                     43: {
                     44:   long exp;
                     45:   unsigned sc;
                     46:   mp_limb_t manh, manl;
                     47:
                     48:   /* BUGS
                     49:
                     50:      1. Should handle Inf and NaN in IEEE specific code.
                     51:      2. Handle Inf and NaN also in default code, to avoid hangs.
                     52:      3. Generalize to handle all BITS_PER_MP_LIMB >= 32.
                     53:      4. This lits is incomplete and misspelled.
                     54:    */
                     55:
                     56:   if (d == 0.0)
                     57:     {
                     58:       rp[0] = 0;
                     59:       rp[1] = 0;
                     60: #if BITS_PER_MP_LIMB == 32
                     61:       rp[2] = 0;
                     62: #endif
                     63:       return 0;
                     64:     }
                     65:
                     66: #if _GMP_IEEE_FLOATS
                     67:   {
                     68: #if defined (__alpha) && __GNUC__ == 2 && __GNUC_MINOR__ == 8
                     69:     /* Work around alpha-specific bug in GCC 2.8.x.  */
                     70:     volatile
                     71: #endif
                     72:     union ieee_double_extract x;
                     73:     x.d = d;
                     74:     exp = x.s.exp;
                     75: #if BITS_PER_MP_LIMB == 64
                     76:     manl = (((mp_limb_t) 1 << 63)
                     77:            | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
                     78:     if (exp == 0)
                     79:       {
                     80:        /* Denormalized number.  Don't try to be clever about this,
                     81:           since it is not an important case to make fast.  */
                     82:        exp = 1;
                     83:        do
                     84:          {
                     85:            manl = manl << 1;
                     86:            exp--;
                     87:          }
                     88:        while ((mp_limb_signed_t) manl >= 0);
                     89:       }
                     90: #else
                     91:     manh = ((mp_limb_t) 1 << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
                     92:     manl = x.s.manl << 11;
                     93:     if (exp == 0)
                     94:       {
                     95:        /* Denormalized number.  Don't try to be clever about this,
                     96:           since it is not an important case to make fast.  */
                     97:        exp = 1;
                     98:        do
                     99:          {
                    100:            manh = (manh << 1) | (manl >> 31);
                    101:            manl = manl << 1;
                    102:            exp--;
                    103:          }
                    104:        while ((mp_limb_signed_t) manh >= 0);
                    105:       }
                    106: #endif
                    107:     exp -= 1022;               /* Remove IEEE bias.  */
                    108:   }
                    109: #else
                    110:   {
                    111:     /* Unknown (or known to be non-IEEE) double format.  */
                    112:     exp = 0;
                    113:     if (d >= 1.0)
                    114:       {
                    115:        if (d * 0.5 == d)
                    116:          abort ();
                    117:
                    118:        while (d >= 32768.0)
                    119:          {
                    120:            d *= (1.0 / 65536.0);
                    121:            exp += 16;
                    122:          }
                    123:        while (d >= 1.0)
                    124:          {
                    125:            d *= 0.5;
                    126:            exp += 1;
                    127:          }
                    128:       }
                    129:     else if (d < 0.5)
                    130:       {
                    131:        while (d < (1.0 / 65536.0))
                    132:          {
                    133:            d *=  65536.0;
                    134:            exp -= 16;
                    135:          }
                    136:        while (d < 0.5)
                    137:          {
                    138:            d *= 2.0;
                    139:            exp -= 1;
                    140:          }
                    141:       }
                    142:
                    143:     d *= MP_BASE_AS_DOUBLE;
                    144: #if BITS_PER_MP_LIMB == 64
                    145:     manl = d;
                    146: #else
                    147:     manh = d;
                    148:     manl = (d - manh) * MP_BASE_AS_DOUBLE;
                    149: #endif
                    150:   }
                    151: #endif
                    152:
                    153:   sc = (unsigned) exp % BITS_PER_MP_LIMB;
                    154:
                    155:   /* We add something here to get rounding right.  */
                    156:   exp = (exp + 2048) / BITS_PER_MP_LIMB - 2048 / BITS_PER_MP_LIMB + 1;
                    157:
                    158: #if BITS_PER_MP_LIMB == 64
                    159:   if (sc != 0)
                    160:     {
                    161:       rp[1] = manl >> (BITS_PER_MP_LIMB - sc);
                    162:       rp[0] = manl << sc;
                    163:     }
                    164:   else
                    165:     {
                    166:       rp[1] = manl;
                    167:       rp[0] = 0;
                    168:       exp--;
                    169:     }
                    170: #else
                    171:   if (sc != 0)
                    172:     {
                    173:       rp[2] = manh >> (BITS_PER_MP_LIMB - sc);
                    174:       rp[1] = (manl >> (BITS_PER_MP_LIMB - sc)) | (manh << sc);
                    175:       rp[0] = manl << sc;
                    176:     }
                    177:   else
                    178:     {
                    179:       rp[2] = manh;
                    180:       rp[1] = manl;
                    181:       rp[0] = 0;
                    182:       exp--;
                    183:     }
                    184: #endif
                    185:
                    186:   return exp;
                    187: }

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