1 /* __gmp_extract_double -- convert from double to array of mp_limb_t.
3 Copyright 1996, 1999, 2000, 2001, 2002, 2006, 2012 Free Software Foundation,
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
25 #undef _GMP_IEEE_FLOATS
28 #ifndef _GMP_IEEE_FLOATS
29 #define _GMP_IEEE_FLOATS 0
32 /* Extract a non-negative double in d. */
35 __gmp_extract_double (mp_ptr rp, double d)
39 #ifdef _LONG_LONG_LIMB
40 #define BITS_PER_PART 64 /* somewhat bogus */
41 unsigned long long int manl;
43 #define BITS_PER_PART GMP_LIMB_BITS
44 unsigned long int manh, manl;
49 1. Should handle Inf and NaN in IEEE specific code.
50 2. Handle Inf and NaN also in default code, to avoid hangs.
51 3. Generalize to handle all GMP_LIMB_BITS >= 32.
52 4. This lits is incomplete and misspelled.
59 MPN_ZERO (rp, LIMBS_PER_DOUBLE);
65 #if defined (__alpha) && __GNUC__ == 2 && __GNUC_MINOR__ == 8
66 /* Work around alpha-specific bug in GCC 2.8.x. */
69 union ieee_double_extract x;
72 #if BITS_PER_PART == 64 /* generalize this to BITS_PER_PART > BITS_IN_MANTISSA */
73 manl = (((mp_limb_t) 1 << 63)
74 | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
77 /* Denormalized number. Don't try to be clever about this,
78 since it is not an important case to make fast. */
85 while ((manl & GMP_LIMB_HIGHBIT) == 0);
88 #if BITS_PER_PART == 32
89 manh = ((mp_limb_t) 1 << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
90 manl = x.s.manl << 11;
93 /* Denormalized number. Don't try to be clever about this,
94 since it is not an important case to make fast. */
98 manh = (manh << 1) | (manl >> 31);
102 while ((manh & GMP_LIMB_HIGHBIT) == 0);
105 #if BITS_PER_PART != 32 && BITS_PER_PART != 64
106 You need to generalize the code above to handle this.
108 exp -= 1022; /* Remove IEEE bias. */
112 /* Unknown (or known to be non-IEEE) double format. */
116 ASSERT_ALWAYS (d * 0.5 != d);
120 d *= (1.0 / 65536.0);
131 while (d < (1.0 / 65536.0))
143 d *= (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2)));
144 #if BITS_PER_PART == 64
147 #if BITS_PER_PART == 32
149 manl = (d - manh) * (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2)));
154 sc = (unsigned) (exp + 64 * GMP_NUMB_BITS) % GMP_NUMB_BITS;
156 /* We add something here to get rounding right. */
157 exp = (exp + 64 * GMP_NUMB_BITS) / GMP_NUMB_BITS - 64 * GMP_NUMB_BITS / GMP_NUMB_BITS + 1;
159 #if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 2
160 #if GMP_NAIL_BITS == 0
163 rp[1] = manl >> (GMP_LIMB_BITS - sc);
173 if (sc > GMP_NAIL_BITS)
175 rp[1] = manl >> (GMP_LIMB_BITS - sc);
176 rp[0] = (manl << (sc - GMP_NAIL_BITS)) & GMP_NUMB_MASK;
182 rp[1] = manl >> GMP_NAIL_BITS;
183 rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS) & GMP_NUMB_MASK;
188 rp[1] = manl >> (GMP_LIMB_BITS - sc);
189 rp[0] = (manl >> (GMP_NAIL_BITS - sc)) & GMP_NUMB_MASK;
195 #if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 3
196 if (sc > GMP_NAIL_BITS)
198 rp[2] = manl >> (GMP_LIMB_BITS - sc);
199 rp[1] = (manl << sc - GMP_NAIL_BITS) & GMP_NUMB_MASK;
200 if (sc >= 2 * GMP_NAIL_BITS)
203 rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK;
209 rp[2] = manl >> GMP_NAIL_BITS;
210 rp[1] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS) & GMP_NUMB_MASK;
216 rp[2] = manl >> (GMP_LIMB_BITS - sc);
217 rp[1] = (manl >> GMP_NAIL_BITS - sc) & GMP_NUMB_MASK;
218 rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK;
223 #if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE == 3
224 #if GMP_NAIL_BITS == 0
227 rp[2] = manh >> (GMP_LIMB_BITS - sc);
228 rp[1] = (manh << sc) | (manl >> (GMP_LIMB_BITS - sc));
239 if (sc > GMP_NAIL_BITS)
241 rp[2] = (manh >> (GMP_LIMB_BITS - sc));
242 rp[1] = ((manh << (sc - GMP_NAIL_BITS)) |
243 (manl >> (GMP_LIMB_BITS - sc + GMP_NAIL_BITS))) & GMP_NUMB_MASK;
244 if (sc >= 2 * GMP_NAIL_BITS)
245 rp[0] = (manl << sc - 2 * GMP_NAIL_BITS) & GMP_NUMB_MASK;
247 rp[0] = manl >> (2 * GMP_NAIL_BITS - sc) & GMP_NUMB_MASK;
253 rp[2] = manh >> GMP_NAIL_BITS;
254 rp[1] = ((manh << GMP_NUMB_BITS - GMP_NAIL_BITS) | (manl >> 2 * GMP_NAIL_BITS)) & GMP_NUMB_MASK;
255 rp[0] = (manl << GMP_NUMB_BITS - 2 * GMP_NAIL_BITS) & GMP_NUMB_MASK;
260 rp[2] = (manh >> (GMP_LIMB_BITS - sc));
261 rp[1] = (manh >> (GMP_NAIL_BITS - sc)) & GMP_NUMB_MASK;
262 rp[0] = ((manh << (GMP_NUMB_BITS - GMP_NAIL_BITS + sc))
263 | (manl >> (GMP_LIMB_BITS - (GMP_NUMB_BITS - GMP_NAIL_BITS + sc)))) & GMP_NUMB_MASK;
269 #if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE > 3
274 for (i = LIMBS_PER_DOUBLE - 1; i >= 0; i--)
276 rp[i] = manh >> (BITS_PER_ULONG - GMP_NUMB_BITS);
277 manh = ((manh << GMP_NUMB_BITS)
278 | (manl >> (BITS_PER_ULONG - GMP_NUMB_BITS)));
279 manl = manl << GMP_NUMB_BITS;
287 rp[LIMBS_PER_DOUBLE - 1] = (manh >> (GMP_LIMB_BITS - sc));
288 manh = (manh << sc) | (manl >> (GMP_LIMB_BITS - sc));
290 for (i = LIMBS_PER_DOUBLE - 2; i >= 0; i--)
292 rp[i] = manh >> (BITS_PER_ULONG - GMP_NUMB_BITS);
293 manh = ((manh << GMP_NUMB_BITS)
294 | (manl >> (BITS_PER_ULONG - GMP_NUMB_BITS)));
295 manl = manl << GMP_NUMB_BITS;