[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     ! 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>