1 /* mpfr_set_ld -- convert a machine long double to
2 a multiple precision floating-point number
4 Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by the Arenaire and Cacao projects, INRIA.
7 This file is part of the GNU MPFR Library.
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or (at your
12 option) any later version.
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
26 #define MPFR_NEED_LONGLONG_H
27 #include "mpfr-impl.h"
29 /* Various i386 systems have been seen with float.h LDBL constants equal to
30 the DBL ones, whereas they ought to be bigger, reflecting the 10-byte
31 IEEE extended format on that processor. gcc 3.2.1 on FreeBSD and Solaris
32 has been seen with the problem, and gcc 2.95.4 on FreeBSD 4.7. */
34 #if HAVE_LDOUBLE_IEEE_EXT_LITTLE
37 long double dummy
; /* for memory alignment */
39 { '\377','\377','\377','\377',
40 '\377','\377','\377','\377',
43 #define MPFR_LDBL_MAX (* (const long double *) ldbl_max_struct.bytes)
45 #define MPFR_LDBL_MAX LDBL_MAX
48 #ifndef HAVE_LDOUBLE_IEEE_EXT_LITTLE
52 mpfr_set_ld (mpfr_ptr r
, long double d
, mp_rnd_t rnd_mode
)
55 int inexact
, shift_exp
;
57 MPFR_SAVE_EXPO_DECL (expo
);
60 LONGDOUBLE_NAN_ACTION (d
, goto nan
);
63 if (d
> MPFR_LDBL_MAX
)
68 else if (d
< -MPFR_LDBL_MAX
)
75 return mpfr_set_d (r
, (double) d
, rnd_mode
);
77 mpfr_init2 (t
, MPFR_LDBL_MANT_DIG
);
78 mpfr_init2 (u
, IEEE_DBL_MANT_DIG
);
80 MPFR_SAVE_EXPO_MARK (expo
);
84 MPFR_SET_ZERO (t
); /* The sign doesn't matter. */
85 shift_exp
= 0; /* invariant: remainder to deal with is d*2^shift_exp */
86 while (x
!= (long double) 0.0)
88 /* Check overflow of double */
89 if (x
> (long double) DBL_MAX
|| (-x
) > (long double) DBL_MAX
)
91 long double div9
, div10
, div11
, div12
, div13
;
93 #define TWO_64 18446744073709551616.0 /* 2^64 */
94 #define TWO_128 (TWO_64 * TWO_64)
95 #define TWO_256 (TWO_128 * TWO_128)
96 div9
= (long double) (double) (TWO_256
* TWO_256
); /* 2^(2^9) */
98 div11
= div10
* div10
; /* 2^(2^11) */
99 div12
= div11
* div11
; /* 2^(2^12) */
100 div13
= div12
* div12
; /* 2^(2^13) */
101 if (ABS (x
) >= div13
)
103 x
/= div13
; /* exact */
106 if (ABS (x
) >= div12
)
108 x
/= div12
; /* exact */
111 if (ABS (x
) >= div11
)
113 x
/= div11
; /* exact */
116 if (ABS (x
) >= div10
)
118 x
/= div10
; /* exact */
121 /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
122 therefore we have one extra exponent reduction step */
125 x
/= div9
; /* exact */
128 } /* Check overflow of double */
131 long double div9
, div10
, div11
;
133 div9
= (long double) (double) 7.4583407312002067432909653e-155;
134 /* div9 = 2^(-2^9) */
135 div10
= div9
* div9
; /* 2^(-2^10) */
136 div11
= div10
* div10
; /* 2^(-2^11) if extended precision */
137 /* since -DBL_MAX <= x <= DBL_MAX, the cast to double should not
139 if (ABS(x
) < div10
&&
140 div11
!= (long double) 0.0 &&
141 div11
/ div10
== div10
) /* possible underflow */
143 long double div12
, div13
;
144 /* After the divisions, any bit of x must be >= div10,
145 hence the possible division by div9. */
146 div12
= div11
* div11
; /* 2^(-2^12) */
147 div13
= div12
* div12
; /* 2^(-2^13) */
148 if (ABS (x
) <= div13
)
150 x
/= div13
; /* exact */
153 if (ABS (x
) <= div12
)
155 x
/= div12
; /* exact */
158 if (ABS (x
) <= div11
)
160 x
/= div11
; /* exact */
163 if (ABS (x
) <= div10
)
165 x
/= div10
; /* exact */
170 x
/= div9
; /* exact */
176 inexact
= mpfr_set_d (u
, (double) x
, GMP_RNDZ
);
177 MPFR_ASSERTD (inexact
== 0);
178 if (mpfr_add (t
, t
, u
, GMP_RNDZ
) != 0)
180 if (!mpfr_number_p (t
))
182 /* Inexact. This cannot happen unless the C implementation
183 "lies" on the precision or when long doubles are
184 implemented with FP expansions like under Mac OS X. */
185 if (MPFR_PREC (t
) != MPFR_PREC (r
) + 1)
187 /* We assume that MPFR_PREC (r) < MPFR_PREC_MAX.
188 The precision MPFR_PREC (r) + 1 allows us to
189 deduce the rounding bit and the sticky bit. */
190 mpfr_set_prec (t
, MPFR_PREC (r
) + 1);
198 /* Since mpfr_add was inexact, the sticky bit is 1. */
200 rb_mask
= MPFR_LIMB_ONE
<<
201 (BITS_PER_MP_LIMB
- 1 -
202 (MPFR_PREC (r
) & (BITS_PER_MP_LIMB
- 1)));
203 if (rnd_mode
== GMP_RNDN
)
204 rnd_mode
= (*tp
& rb_mask
) ^ MPFR_IS_NEG (t
) ?
210 x
-= (long double) mpfr_get_d1 (u
); /* exact */
214 inexact
= mpfr_mul_2si (r
, t
, shift_exp
, rnd_mode
);
218 MPFR_SAVE_EXPO_FREE (expo
);
219 return mpfr_check_range (r
, inexact
, rnd_mode
);
226 #else /* IEEE Extended Little Endian Code */
229 mpfr_set_ld (mpfr_ptr r
, long double d
, mp_rnd_t rnd_mode
)
231 int inexact
, i
, k
, cnt
;
233 mp_limb_t tmpmant
[MPFR_LIMBS_PER_LONG_DOUBLE
];
234 mpfr_long_double_t x
;
237 MPFR_SAVE_EXPO_DECL (expo
);
240 if (MPFR_UNLIKELY (d
!= d
))
246 else if (MPFR_UNLIKELY (d
> MPFR_LDBL_MAX
))
252 else if (MPFR_UNLIKELY (d
< -MPFR_LDBL_MAX
))
259 else if (MPFR_UNLIKELY (d
== 0.0))
270 /* now d is neither 0, nor NaN nor Inf */
271 MPFR_SAVE_EXPO_MARK (expo
);
273 MPFR_MANT (tmp
) = tmpmant
;
274 MPFR_PREC (tmp
) = 64;
278 signd
= MPFR_SIGN_POS
;
281 signd
= MPFR_SIGN_NEG
;
285 /* Extract mantissa */
286 #if BITS_PER_MP_LIMB >= 64
287 tmpmant
[0] = ((mp_limb_t
) x
.s
.manh
<< 32) | ((mp_limb_t
) x
.s
.manl
);
289 tmpmant
[0] = (mp_limb_t
) x
.s
.manl
;
290 tmpmant
[1] = (mp_limb_t
) x
.s
.manh
;
293 /* Normalize mantissa */
294 i
= MPFR_LIMBS_PER_LONG_DOUBLE
;
295 MPN_NORMALIZE_NOT_ZERO (tmpmant
, i
);
296 k
= MPFR_LIMBS_PER_LONG_DOUBLE
- i
;
297 count_leading_zeros (cnt
, tmpmant
[i
- 1]);
298 if (MPFR_LIKELY (cnt
!= 0))
299 mpn_lshift (tmpmant
+ k
, tmpmant
, i
, cnt
);
301 MPN_COPY (tmpmant
+ k
, tmpmant
, i
);
302 if (MPFR_UNLIKELY (k
!= 0))
303 MPN_ZERO (tmpmant
, k
);
306 exp
= (mp_exp_t
) ((x
.s
.exph
<< 8) + x
.s
.expl
); /* 15-bit unsigned int */
307 if (MPFR_UNLIKELY (exp
== 0))
312 MPFR_SET_EXP (tmp
, exp
- cnt
- k
* BITS_PER_MP_LIMB
);
315 inexact
= mpfr_set4 (r
, tmp
, rnd_mode
, signd
);
317 MPFR_SAVE_EXPO_FREE (expo
);
318 return mpfr_check_range (r
, inexact
, rnd_mode
);