1f9f848faSopenharmony_ci/****************************************************************
2f9f848faSopenharmony_ci
3f9f848faSopenharmony_ciThe author of this software is David M. Gay.
4f9f848faSopenharmony_ci
5f9f848faSopenharmony_ciCopyright (C) 1998-2001 by Lucent Technologies
6f9f848faSopenharmony_ciAll Rights Reserved
7f9f848faSopenharmony_ci
8f9f848faSopenharmony_ciPermission to use, copy, modify, and distribute this software and
9f9f848faSopenharmony_ciits documentation for any purpose and without fee is hereby
10f9f848faSopenharmony_cigranted, provided that the above copyright notice appear in all
11f9f848faSopenharmony_cicopies and that both that the copyright notice and this
12f9f848faSopenharmony_cipermission notice and warranty disclaimer appear in supporting
13f9f848faSopenharmony_cidocumentation, and that the name of Lucent or any of its entities
14f9f848faSopenharmony_cinot be used in advertising or publicity pertaining to
15f9f848faSopenharmony_cidistribution of the software without specific, written prior
16f9f848faSopenharmony_cipermission.
17f9f848faSopenharmony_ci
18f9f848faSopenharmony_ciLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19f9f848faSopenharmony_ciINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20f9f848faSopenharmony_ciIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21f9f848faSopenharmony_ciSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22f9f848faSopenharmony_ciWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23f9f848faSopenharmony_ciIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24f9f848faSopenharmony_ciARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25f9f848faSopenharmony_ciTHIS SOFTWARE.
26f9f848faSopenharmony_ci
27f9f848faSopenharmony_ci****************************************************************/
28f9f848faSopenharmony_ci
29f9f848faSopenharmony_ci/* Please send bug reports to David M. Gay (dmg at acm dot org,
30f9f848faSopenharmony_ci * with " at " changed at "@" and " dot " changed to ".").	*/
31f9f848faSopenharmony_ci
32f9f848faSopenharmony_ci/* $FreeBSD$ */
33f9f848faSopenharmony_ci
34f9f848faSopenharmony_ci#include "gdtoaimp.h"
35f9f848faSopenharmony_ci#ifndef NO_FENV_H
36f9f848faSopenharmony_ci#include <fenv.h>
37f9f848faSopenharmony_ci#endif
38f9f848faSopenharmony_ci
39f9f848faSopenharmony_ci#ifdef USE_LOCALE
40f9f848faSopenharmony_ci#include "locale.h"
41f9f848faSopenharmony_ci#endif
42f9f848faSopenharmony_ci
43f9f848faSopenharmony_ci#ifdef IEEE_Arith
44f9f848faSopenharmony_ci#ifndef NO_IEEE_Scale
45f9f848faSopenharmony_ci#define Avoid_Underflow
46f9f848faSopenharmony_ci#undef tinytens
47f9f848faSopenharmony_ci/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */
48f9f848faSopenharmony_ci/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
49f9f848faSopenharmony_cistatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
50f9f848faSopenharmony_ci		9007199254740992.*9007199254740992.e-256
51f9f848faSopenharmony_ci		};
52f9f848faSopenharmony_ci#endif
53f9f848faSopenharmony_ci#endif
54f9f848faSopenharmony_ci
55f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
56f9f848faSopenharmony_ci#undef Check_FLT_ROUNDS
57f9f848faSopenharmony_ci#define Check_FLT_ROUNDS
58f9f848faSopenharmony_ci#else
59f9f848faSopenharmony_ci#define Rounding Flt_Rounds
60f9f848faSopenharmony_ci#endif
61f9f848faSopenharmony_ci
62f9f848faSopenharmony_ci#ifdef Avoid_Underflow /*{*/
63f9f848faSopenharmony_ci static double
64f9f848faSopenharmony_cisulp
65f9f848faSopenharmony_ci#ifdef KR_headers
66f9f848faSopenharmony_ci	(x, scale) U *x; int scale;
67f9f848faSopenharmony_ci#else
68f9f848faSopenharmony_ci	(U *x, int scale)
69f9f848faSopenharmony_ci#endif
70f9f848faSopenharmony_ci{
71f9f848faSopenharmony_ci	U u;
72f9f848faSopenharmony_ci	double rv;
73f9f848faSopenharmony_ci	int i;
74f9f848faSopenharmony_ci
75f9f848faSopenharmony_ci	rv = ulp(x);
76f9f848faSopenharmony_ci	if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
77f9f848faSopenharmony_ci		return rv; /* Is there an example where i <= 0 ? */
78f9f848faSopenharmony_ci	word0(&u) = Exp_1 + (i << Exp_shift);
79f9f848faSopenharmony_ci	word1(&u) = 0;
80f9f848faSopenharmony_ci	return rv * u.d;
81f9f848faSopenharmony_ci	}
82f9f848faSopenharmony_ci#endif /*}*/
83f9f848faSopenharmony_ci
84f9f848faSopenharmony_cistatic double
85f9f848faSopenharmony_cistrtod_l
86f9f848faSopenharmony_ci#ifdef KR_headers
87f9f848faSopenharmony_ci	(s00, se, loc) CONST char *s00; char **se; locale_t loc
88f9f848faSopenharmony_ci#else
89f9f848faSopenharmony_ci	(CONST char *s00, char **se, locale_t loc)
90f9f848faSopenharmony_ci#endif
91f9f848faSopenharmony_ci{
92f9f848faSopenharmony_ci#ifdef Avoid_Underflow
93f9f848faSopenharmony_ci	int scale;
94f9f848faSopenharmony_ci#endif
95f9f848faSopenharmony_ci	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
96f9f848faSopenharmony_ci		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
97f9f848faSopenharmony_ci	CONST char *s, *s0, *s1;
98f9f848faSopenharmony_ci	double aadj;
99f9f848faSopenharmony_ci	Long L;
100f9f848faSopenharmony_ci	U adj, aadj1, rv, rv0;
101f9f848faSopenharmony_ci	ULong y, z;
102f9f848faSopenharmony_ci	Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
103f9f848faSopenharmony_ci#ifdef Avoid_Underflow
104f9f848faSopenharmony_ci	ULong Lsb, Lsb1;
105f9f848faSopenharmony_ci#endif
106f9f848faSopenharmony_ci#ifdef SET_INEXACT
107f9f848faSopenharmony_ci	int inexact, oldinexact;
108f9f848faSopenharmony_ci#endif
109f9f848faSopenharmony_ci#ifdef USE_LOCALE /*{{*/
110f9f848faSopenharmony_ci#ifdef NO_LOCALE_CACHE
111f9f848faSopenharmony_ci	char *decimalpoint = localeconv_l(loc)->decimal_point;
112f9f848faSopenharmony_ci	int dplen = strlen(decimalpoint);
113f9f848faSopenharmony_ci#else
114f9f848faSopenharmony_ci	char *decimalpoint;
115f9f848faSopenharmony_ci	static char *decimalpoint_cache;
116f9f848faSopenharmony_ci	static int dplen;
117f9f848faSopenharmony_ci	if (!(s0 = decimalpoint_cache)) {
118f9f848faSopenharmony_ci		s0 = localeconv_l(loc)->decimal_point;
119f9f848faSopenharmony_ci		if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
120f9f848faSopenharmony_ci			strcpy(decimalpoint_cache, s0);
121f9f848faSopenharmony_ci			s0 = decimalpoint_cache;
122f9f848faSopenharmony_ci			}
123f9f848faSopenharmony_ci		dplen = strlen(s0);
124f9f848faSopenharmony_ci		}
125f9f848faSopenharmony_ci	decimalpoint = (char*)s0;
126f9f848faSopenharmony_ci#endif /*NO_LOCALE_CACHE*/
127f9f848faSopenharmony_ci#else  /*USE_LOCALE}{*/
128f9f848faSopenharmony_ci#define dplen 1
129f9f848faSopenharmony_ci#endif /*USE_LOCALE}}*/
130f9f848faSopenharmony_ci
131f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS /*{*/
132f9f848faSopenharmony_ci	int Rounding;
133f9f848faSopenharmony_ci#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
134f9f848faSopenharmony_ci	Rounding = Flt_Rounds;
135f9f848faSopenharmony_ci#else /*}{*/
136f9f848faSopenharmony_ci	Rounding = 1;
137f9f848faSopenharmony_ci	switch(fegetround()) {
138f9f848faSopenharmony_ci	  case FE_TOWARDZERO:	Rounding = 0; break;
139f9f848faSopenharmony_ci	  case FE_UPWARD:	Rounding = 2; break;
140f9f848faSopenharmony_ci	  case FE_DOWNWARD:	Rounding = 3;
141f9f848faSopenharmony_ci	  }
142f9f848faSopenharmony_ci#endif /*}}*/
143f9f848faSopenharmony_ci#endif /*}*/
144f9f848faSopenharmony_ci
145f9f848faSopenharmony_ci	sign = nz0 = nz = decpt = 0;
146f9f848faSopenharmony_ci	dval(&rv) = 0.;
147f9f848faSopenharmony_ci	for(s = s00;;s++) switch(*s) {
148f9f848faSopenharmony_ci		case '-':
149f9f848faSopenharmony_ci			sign = 1;
150f9f848faSopenharmony_ci			/* no break */
151f9f848faSopenharmony_ci		case '+':
152f9f848faSopenharmony_ci			if (*++s)
153f9f848faSopenharmony_ci				goto break2;
154f9f848faSopenharmony_ci			/* no break */
155f9f848faSopenharmony_ci		case 0:
156f9f848faSopenharmony_ci			goto ret0;
157f9f848faSopenharmony_ci		case '\t':
158f9f848faSopenharmony_ci		case '\n':
159f9f848faSopenharmony_ci		case '\v':
160f9f848faSopenharmony_ci		case '\f':
161f9f848faSopenharmony_ci		case '\r':
162f9f848faSopenharmony_ci		case ' ':
163f9f848faSopenharmony_ci			continue;
164f9f848faSopenharmony_ci		default:
165f9f848faSopenharmony_ci			goto break2;
166f9f848faSopenharmony_ci		}
167f9f848faSopenharmony_ci break2:
168f9f848faSopenharmony_ci	if (*s == '0') {
169f9f848faSopenharmony_ci#ifndef NO_HEX_FP /*{*/
170f9f848faSopenharmony_ci		{
171f9f848faSopenharmony_ci		static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
172f9f848faSopenharmony_ci		Long exp;
173f9f848faSopenharmony_ci		ULong bits[2];
174f9f848faSopenharmony_ci		switch(s[1]) {
175f9f848faSopenharmony_ci		  case 'x':
176f9f848faSopenharmony_ci		  case 'X':
177f9f848faSopenharmony_ci			{
178f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
179f9f848faSopenharmony_ci			FPI fpi1 = fpi;
180f9f848faSopenharmony_ci			fpi1.rounding = Rounding;
181f9f848faSopenharmony_ci#else
182f9f848faSopenharmony_ci#define fpi1 fpi
183f9f848faSopenharmony_ci#endif
184f9f848faSopenharmony_ci			switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
185f9f848faSopenharmony_ci			  case STRTOG_NoNumber:
186f9f848faSopenharmony_ci				s = s00;
187f9f848faSopenharmony_ci				sign = 0;
188f9f848faSopenharmony_ci			  case STRTOG_Zero:
189f9f848faSopenharmony_ci				break;
190f9f848faSopenharmony_ci			  default:
191f9f848faSopenharmony_ci				if (bb) {
192f9f848faSopenharmony_ci					copybits(bits, fpi.nbits, bb);
193f9f848faSopenharmony_ci					Bfree(bb);
194f9f848faSopenharmony_ci					}
195f9f848faSopenharmony_ci				ULtod(((U*)&rv)->L, bits, exp, i);
196f9f848faSopenharmony_ci			  }}
197f9f848faSopenharmony_ci			goto ret;
198f9f848faSopenharmony_ci		  }
199f9f848faSopenharmony_ci		}
200f9f848faSopenharmony_ci#endif /*}*/
201f9f848faSopenharmony_ci		nz0 = 1;
202f9f848faSopenharmony_ci		while(*++s == '0') ;
203f9f848faSopenharmony_ci		if (!*s)
204f9f848faSopenharmony_ci			goto ret;
205f9f848faSopenharmony_ci		}
206f9f848faSopenharmony_ci	s0 = s;
207f9f848faSopenharmony_ci	y = z = 0;
208f9f848faSopenharmony_ci	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
209f9f848faSopenharmony_ci		if (nd < 9)
210f9f848faSopenharmony_ci			y = 10*y + c - '0';
211f9f848faSopenharmony_ci		else if (nd < 16)
212f9f848faSopenharmony_ci			z = 10*z + c - '0';
213f9f848faSopenharmony_ci	nd0 = nd;
214f9f848faSopenharmony_ci#ifdef USE_LOCALE
215f9f848faSopenharmony_ci	if (c == *decimalpoint) {
216f9f848faSopenharmony_ci		for(i = 1; decimalpoint[i]; ++i)
217f9f848faSopenharmony_ci			if (s[i] != decimalpoint[i])
218f9f848faSopenharmony_ci				goto dig_done;
219f9f848faSopenharmony_ci		s += i;
220f9f848faSopenharmony_ci		c = *s;
221f9f848faSopenharmony_ci#else
222f9f848faSopenharmony_ci	if (c == '.') {
223f9f848faSopenharmony_ci		c = *++s;
224f9f848faSopenharmony_ci#endif
225f9f848faSopenharmony_ci		decpt = 1;
226f9f848faSopenharmony_ci		if (!nd) {
227f9f848faSopenharmony_ci			for(; c == '0'; c = *++s)
228f9f848faSopenharmony_ci				nz++;
229f9f848faSopenharmony_ci			if (c > '0' && c <= '9') {
230f9f848faSopenharmony_ci				s0 = s;
231f9f848faSopenharmony_ci				nf += nz;
232f9f848faSopenharmony_ci				nz = 0;
233f9f848faSopenharmony_ci				goto have_dig;
234f9f848faSopenharmony_ci				}
235f9f848faSopenharmony_ci			goto dig_done;
236f9f848faSopenharmony_ci			}
237f9f848faSopenharmony_ci		for(; c >= '0' && c <= '9'; c = *++s) {
238f9f848faSopenharmony_ci have_dig:
239f9f848faSopenharmony_ci			nz++;
240f9f848faSopenharmony_ci			if (c -= '0') {
241f9f848faSopenharmony_ci				nf += nz;
242f9f848faSopenharmony_ci				for(i = 1; i < nz; i++)
243f9f848faSopenharmony_ci					if (nd++ < 9)
244f9f848faSopenharmony_ci						y *= 10;
245f9f848faSopenharmony_ci					else if (nd <= DBL_DIG + 1)
246f9f848faSopenharmony_ci						z *= 10;
247f9f848faSopenharmony_ci				if (nd++ < 9)
248f9f848faSopenharmony_ci					y = 10*y + c;
249f9f848faSopenharmony_ci				else if (nd <= DBL_DIG + 1)
250f9f848faSopenharmony_ci					z = 10*z + c;
251f9f848faSopenharmony_ci				nz = 0;
252f9f848faSopenharmony_ci				}
253f9f848faSopenharmony_ci			}
254f9f848faSopenharmony_ci		}/*}*/
255f9f848faSopenharmony_ci dig_done:
256f9f848faSopenharmony_ci	e = 0;
257f9f848faSopenharmony_ci	if (c == 'e' || c == 'E') {
258f9f848faSopenharmony_ci		if (!nd && !nz && !nz0) {
259f9f848faSopenharmony_ci			goto ret0;
260f9f848faSopenharmony_ci			}
261f9f848faSopenharmony_ci		s00 = s;
262f9f848faSopenharmony_ci		esign = 0;
263f9f848faSopenharmony_ci		switch(c = *++s) {
264f9f848faSopenharmony_ci			case '-':
265f9f848faSopenharmony_ci				esign = 1;
266f9f848faSopenharmony_ci			case '+':
267f9f848faSopenharmony_ci				c = *++s;
268f9f848faSopenharmony_ci			}
269f9f848faSopenharmony_ci		if (c >= '0' && c <= '9') {
270f9f848faSopenharmony_ci			while(c == '0')
271f9f848faSopenharmony_ci				c = *++s;
272f9f848faSopenharmony_ci			if (c > '0' && c <= '9') {
273f9f848faSopenharmony_ci				L = c - '0';
274f9f848faSopenharmony_ci				s1 = s;
275f9f848faSopenharmony_ci				while((c = *++s) >= '0' && c <= '9')
276f9f848faSopenharmony_ci					L = 10*L + c - '0';
277f9f848faSopenharmony_ci				if (s - s1 > 8 || L > 19999)
278f9f848faSopenharmony_ci					/* Avoid confusion from exponents
279f9f848faSopenharmony_ci					 * so large that e might overflow.
280f9f848faSopenharmony_ci					 */
281f9f848faSopenharmony_ci					e = 19999; /* safe for 16 bit ints */
282f9f848faSopenharmony_ci				else
283f9f848faSopenharmony_ci					e = (int)L;
284f9f848faSopenharmony_ci				if (esign)
285f9f848faSopenharmony_ci					e = -e;
286f9f848faSopenharmony_ci				}
287f9f848faSopenharmony_ci			else
288f9f848faSopenharmony_ci				e = 0;
289f9f848faSopenharmony_ci			}
290f9f848faSopenharmony_ci		else
291f9f848faSopenharmony_ci			s = s00;
292f9f848faSopenharmony_ci		}
293f9f848faSopenharmony_ci	if (!nd) {
294f9f848faSopenharmony_ci		if (!nz && !nz0) {
295f9f848faSopenharmony_ci#ifdef INFNAN_CHECK
296f9f848faSopenharmony_ci			/* Check for Nan and Infinity */
297f9f848faSopenharmony_ci			ULong bits[2];
298f9f848faSopenharmony_ci			static FPI fpinan =	/* only 52 explicit bits */
299f9f848faSopenharmony_ci				{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
300f9f848faSopenharmony_ci			if (!decpt)
301f9f848faSopenharmony_ci			 switch(c) {
302f9f848faSopenharmony_ci			  case 'i':
303f9f848faSopenharmony_ci			  case 'I':
304f9f848faSopenharmony_ci				if (match(&s,"nf")) {
305f9f848faSopenharmony_ci					--s;
306f9f848faSopenharmony_ci					if (!match(&s,"inity"))
307f9f848faSopenharmony_ci						++s;
308f9f848faSopenharmony_ci					word0(&rv) = 0x7ff00000;
309f9f848faSopenharmony_ci					word1(&rv) = 0;
310f9f848faSopenharmony_ci					goto ret;
311f9f848faSopenharmony_ci					}
312f9f848faSopenharmony_ci				break;
313f9f848faSopenharmony_ci			  case 'n':
314f9f848faSopenharmony_ci			  case 'N':
315f9f848faSopenharmony_ci				if (match(&s, "an")) {
316f9f848faSopenharmony_ci#ifndef No_Hex_NaN
317f9f848faSopenharmony_ci					if (*s == '(' /*)*/
318f9f848faSopenharmony_ci					 && hexnan(&s, &fpinan, bits)
319f9f848faSopenharmony_ci							== STRTOG_NaNbits) {
320f9f848faSopenharmony_ci						word0(&rv) = 0x7ff80000 | bits[1];
321f9f848faSopenharmony_ci						word1(&rv) = bits[0];
322f9f848faSopenharmony_ci						}
323f9f848faSopenharmony_ci					else {
324f9f848faSopenharmony_ci#endif
325f9f848faSopenharmony_ci						word0(&rv) = NAN_WORD0;
326f9f848faSopenharmony_ci						word1(&rv) = NAN_WORD1;
327f9f848faSopenharmony_ci#ifndef No_Hex_NaN
328f9f848faSopenharmony_ci						}
329f9f848faSopenharmony_ci#endif
330f9f848faSopenharmony_ci					goto ret;
331f9f848faSopenharmony_ci					}
332f9f848faSopenharmony_ci			  }
333f9f848faSopenharmony_ci#endif /* INFNAN_CHECK */
334f9f848faSopenharmony_ci ret0:
335f9f848faSopenharmony_ci			s = s00;
336f9f848faSopenharmony_ci			sign = 0;
337f9f848faSopenharmony_ci			}
338f9f848faSopenharmony_ci		goto ret;
339f9f848faSopenharmony_ci		}
340f9f848faSopenharmony_ci	e1 = e -= nf;
341f9f848faSopenharmony_ci
342f9f848faSopenharmony_ci	/* Now we have nd0 digits, starting at s0, followed by a
343f9f848faSopenharmony_ci	 * decimal point, followed by nd-nd0 digits.  The number we're
344f9f848faSopenharmony_ci	 * after is the integer represented by those digits times
345f9f848faSopenharmony_ci	 * 10**e */
346f9f848faSopenharmony_ci
347f9f848faSopenharmony_ci	if (!nd0)
348f9f848faSopenharmony_ci		nd0 = nd;
349f9f848faSopenharmony_ci	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
350f9f848faSopenharmony_ci	dval(&rv) = y;
351f9f848faSopenharmony_ci	if (k > 9) {
352f9f848faSopenharmony_ci#ifdef SET_INEXACT
353f9f848faSopenharmony_ci		if (k > DBL_DIG)
354f9f848faSopenharmony_ci			oldinexact = get_inexact();
355f9f848faSopenharmony_ci#endif
356f9f848faSopenharmony_ci		dval(&rv) = tens[k - 9] * dval(&rv) + z;
357f9f848faSopenharmony_ci		}
358f9f848faSopenharmony_ci	bd0 = 0;
359f9f848faSopenharmony_ci	if (nd <= DBL_DIG
360f9f848faSopenharmony_ci#ifndef RND_PRODQUOT
361f9f848faSopenharmony_ci#ifndef Honor_FLT_ROUNDS
362f9f848faSopenharmony_ci		&& Flt_Rounds == 1
363f9f848faSopenharmony_ci#endif
364f9f848faSopenharmony_ci#endif
365f9f848faSopenharmony_ci			) {
366f9f848faSopenharmony_ci		if (!e)
367f9f848faSopenharmony_ci			goto ret;
368f9f848faSopenharmony_ci#ifndef ROUND_BIASED_without_Round_Up
369f9f848faSopenharmony_ci		if (e > 0) {
370f9f848faSopenharmony_ci			if (e <= Ten_pmax) {
371f9f848faSopenharmony_ci#ifdef VAX
372f9f848faSopenharmony_ci				goto vax_ovfl_check;
373f9f848faSopenharmony_ci#else
374f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
375f9f848faSopenharmony_ci				/* round correctly FLT_ROUNDS = 2 or 3 */
376f9f848faSopenharmony_ci				if (sign) {
377f9f848faSopenharmony_ci					rv.d = -rv.d;
378f9f848faSopenharmony_ci					sign = 0;
379f9f848faSopenharmony_ci					}
380f9f848faSopenharmony_ci#endif
381f9f848faSopenharmony_ci				/* rv = */ rounded_product(dval(&rv), tens[e]);
382f9f848faSopenharmony_ci				goto ret;
383f9f848faSopenharmony_ci#endif
384f9f848faSopenharmony_ci				}
385f9f848faSopenharmony_ci			i = DBL_DIG - nd;
386f9f848faSopenharmony_ci			if (e <= Ten_pmax + i) {
387f9f848faSopenharmony_ci				/* A fancier test would sometimes let us do
388f9f848faSopenharmony_ci				 * this for larger i values.
389f9f848faSopenharmony_ci				 */
390f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
391f9f848faSopenharmony_ci				/* round correctly FLT_ROUNDS = 2 or 3 */
392f9f848faSopenharmony_ci				if (sign) {
393f9f848faSopenharmony_ci					rv.d = -rv.d;
394f9f848faSopenharmony_ci					sign = 0;
395f9f848faSopenharmony_ci					}
396f9f848faSopenharmony_ci#endif
397f9f848faSopenharmony_ci				e -= i;
398f9f848faSopenharmony_ci				dval(&rv) *= tens[i];
399f9f848faSopenharmony_ci#ifdef VAX
400f9f848faSopenharmony_ci				/* VAX exponent range is so narrow we must
401f9f848faSopenharmony_ci				 * worry about overflow here...
402f9f848faSopenharmony_ci				 */
403f9f848faSopenharmony_ci vax_ovfl_check:
404f9f848faSopenharmony_ci				word0(&rv) -= P*Exp_msk1;
405f9f848faSopenharmony_ci				/* rv = */ rounded_product(dval(&rv), tens[e]);
406f9f848faSopenharmony_ci				if ((word0(&rv) & Exp_mask)
407f9f848faSopenharmony_ci				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
408f9f848faSopenharmony_ci					goto ovfl;
409f9f848faSopenharmony_ci				word0(&rv) += P*Exp_msk1;
410f9f848faSopenharmony_ci#else
411f9f848faSopenharmony_ci				/* rv = */ rounded_product(dval(&rv), tens[e]);
412f9f848faSopenharmony_ci#endif
413f9f848faSopenharmony_ci				goto ret;
414f9f848faSopenharmony_ci				}
415f9f848faSopenharmony_ci			}
416f9f848faSopenharmony_ci#ifndef Inaccurate_Divide
417f9f848faSopenharmony_ci		else if (e >= -Ten_pmax) {
418f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
419f9f848faSopenharmony_ci			/* round correctly FLT_ROUNDS = 2 or 3 */
420f9f848faSopenharmony_ci			if (sign) {
421f9f848faSopenharmony_ci				rv.d = -rv.d;
422f9f848faSopenharmony_ci				sign = 0;
423f9f848faSopenharmony_ci				}
424f9f848faSopenharmony_ci#endif
425f9f848faSopenharmony_ci			/* rv = */ rounded_quotient(dval(&rv), tens[-e]);
426f9f848faSopenharmony_ci			goto ret;
427f9f848faSopenharmony_ci			}
428f9f848faSopenharmony_ci#endif
429f9f848faSopenharmony_ci#endif /* ROUND_BIASED_without_Round_Up */
430f9f848faSopenharmony_ci		}
431f9f848faSopenharmony_ci	e1 += nd - k;
432f9f848faSopenharmony_ci
433f9f848faSopenharmony_ci#ifdef IEEE_Arith
434f9f848faSopenharmony_ci#ifdef SET_INEXACT
435f9f848faSopenharmony_ci	inexact = 1;
436f9f848faSopenharmony_ci	if (k <= DBL_DIG)
437f9f848faSopenharmony_ci		oldinexact = get_inexact();
438f9f848faSopenharmony_ci#endif
439f9f848faSopenharmony_ci#ifdef Avoid_Underflow
440f9f848faSopenharmony_ci	scale = 0;
441f9f848faSopenharmony_ci#endif
442f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
443f9f848faSopenharmony_ci	if (Rounding >= 2) {
444f9f848faSopenharmony_ci		if (sign)
445f9f848faSopenharmony_ci			Rounding = Rounding == 2 ? 0 : 2;
446f9f848faSopenharmony_ci		else
447f9f848faSopenharmony_ci			if (Rounding != 2)
448f9f848faSopenharmony_ci				Rounding = 0;
449f9f848faSopenharmony_ci		}
450f9f848faSopenharmony_ci#endif
451f9f848faSopenharmony_ci#endif /*IEEE_Arith*/
452f9f848faSopenharmony_ci
453f9f848faSopenharmony_ci	/* Get starting approximation = rv * 10**e1 */
454f9f848faSopenharmony_ci
455f9f848faSopenharmony_ci	if (e1 > 0) {
456f9f848faSopenharmony_ci		if ( (i = e1 & 15) !=0)
457f9f848faSopenharmony_ci			dval(&rv) *= tens[i];
458f9f848faSopenharmony_ci		if (e1 &= ~15) {
459f9f848faSopenharmony_ci			if (e1 > DBL_MAX_10_EXP) {
460f9f848faSopenharmony_ci ovfl:
461f9f848faSopenharmony_ci				/* Can't trust HUGE_VAL */
462f9f848faSopenharmony_ci#ifdef IEEE_Arith
463f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
464f9f848faSopenharmony_ci				switch(Rounding) {
465f9f848faSopenharmony_ci				  case 0: /* toward 0 */
466f9f848faSopenharmony_ci				  case 3: /* toward -infinity */
467f9f848faSopenharmony_ci					word0(&rv) = Big0;
468f9f848faSopenharmony_ci					word1(&rv) = Big1;
469f9f848faSopenharmony_ci					break;
470f9f848faSopenharmony_ci				  default:
471f9f848faSopenharmony_ci					word0(&rv) = Exp_mask;
472f9f848faSopenharmony_ci					word1(&rv) = 0;
473f9f848faSopenharmony_ci				  }
474f9f848faSopenharmony_ci#else /*Honor_FLT_ROUNDS*/
475f9f848faSopenharmony_ci				word0(&rv) = Exp_mask;
476f9f848faSopenharmony_ci				word1(&rv) = 0;
477f9f848faSopenharmony_ci#endif /*Honor_FLT_ROUNDS*/
478f9f848faSopenharmony_ci#ifdef SET_INEXACT
479f9f848faSopenharmony_ci				/* set overflow bit */
480f9f848faSopenharmony_ci				dval(&rv0) = 1e300;
481f9f848faSopenharmony_ci				dval(&rv0) *= dval(&rv0);
482f9f848faSopenharmony_ci#endif
483f9f848faSopenharmony_ci#else /*IEEE_Arith*/
484f9f848faSopenharmony_ci				word0(&rv) = Big0;
485f9f848faSopenharmony_ci				word1(&rv) = Big1;
486f9f848faSopenharmony_ci#endif /*IEEE_Arith*/
487f9f848faSopenharmony_ci range_err:
488f9f848faSopenharmony_ci				if (bd0) {
489f9f848faSopenharmony_ci					Bfree(bb);
490f9f848faSopenharmony_ci					Bfree(bd);
491f9f848faSopenharmony_ci					Bfree(bs);
492f9f848faSopenharmony_ci					Bfree(bd0);
493f9f848faSopenharmony_ci					Bfree(delta);
494f9f848faSopenharmony_ci					}
495f9f848faSopenharmony_ci#ifndef NO_ERRNO
496f9f848faSopenharmony_ci				errno = ERANGE;
497f9f848faSopenharmony_ci#endif
498f9f848faSopenharmony_ci				goto ret;
499f9f848faSopenharmony_ci				}
500f9f848faSopenharmony_ci			e1 >>= 4;
501f9f848faSopenharmony_ci			for(j = 0; e1 > 1; j++, e1 >>= 1)
502f9f848faSopenharmony_ci				if (e1 & 1)
503f9f848faSopenharmony_ci					dval(&rv) *= bigtens[j];
504f9f848faSopenharmony_ci		/* The last multiplication could overflow. */
505f9f848faSopenharmony_ci			word0(&rv) -= P*Exp_msk1;
506f9f848faSopenharmony_ci			dval(&rv) *= bigtens[j];
507f9f848faSopenharmony_ci			if ((z = word0(&rv) & Exp_mask)
508f9f848faSopenharmony_ci			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
509f9f848faSopenharmony_ci				goto ovfl;
510f9f848faSopenharmony_ci			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
511f9f848faSopenharmony_ci				/* set to largest number */
512f9f848faSopenharmony_ci				/* (Can't trust DBL_MAX) */
513f9f848faSopenharmony_ci				word0(&rv) = Big0;
514f9f848faSopenharmony_ci				word1(&rv) = Big1;
515f9f848faSopenharmony_ci				}
516f9f848faSopenharmony_ci			else
517f9f848faSopenharmony_ci				word0(&rv) += P*Exp_msk1;
518f9f848faSopenharmony_ci			}
519f9f848faSopenharmony_ci		}
520f9f848faSopenharmony_ci	else if (e1 < 0) {
521f9f848faSopenharmony_ci		e1 = -e1;
522f9f848faSopenharmony_ci		if ( (i = e1 & 15) !=0)
523f9f848faSopenharmony_ci			dval(&rv) /= tens[i];
524f9f848faSopenharmony_ci		if (e1 >>= 4) {
525f9f848faSopenharmony_ci			if (e1 >= 1 << n_bigtens)
526f9f848faSopenharmony_ci				goto undfl;
527f9f848faSopenharmony_ci#ifdef Avoid_Underflow
528f9f848faSopenharmony_ci			if (e1 & Scale_Bit)
529f9f848faSopenharmony_ci				scale = 2*P;
530f9f848faSopenharmony_ci			for(j = 0; e1 > 0; j++, e1 >>= 1)
531f9f848faSopenharmony_ci				if (e1 & 1)
532f9f848faSopenharmony_ci					dval(&rv) *= tinytens[j];
533f9f848faSopenharmony_ci			if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
534f9f848faSopenharmony_ci						>> Exp_shift)) > 0) {
535f9f848faSopenharmony_ci				/* scaled rv is denormal; zap j low bits */
536f9f848faSopenharmony_ci				if (j >= 32) {
537f9f848faSopenharmony_ci					word1(&rv) = 0;
538f9f848faSopenharmony_ci					if (j >= 53)
539f9f848faSopenharmony_ci					 word0(&rv) = (P+2)*Exp_msk1;
540f9f848faSopenharmony_ci					else
541f9f848faSopenharmony_ci					 word0(&rv) &= 0xffffffff << (j-32);
542f9f848faSopenharmony_ci					}
543f9f848faSopenharmony_ci				else
544f9f848faSopenharmony_ci					word1(&rv) &= 0xffffffff << j;
545f9f848faSopenharmony_ci				}
546f9f848faSopenharmony_ci#else
547f9f848faSopenharmony_ci			for(j = 0; e1 > 1; j++, e1 >>= 1)
548f9f848faSopenharmony_ci				if (e1 & 1)
549f9f848faSopenharmony_ci					dval(&rv) *= tinytens[j];
550f9f848faSopenharmony_ci			/* The last multiplication could underflow. */
551f9f848faSopenharmony_ci			dval(&rv0) = dval(&rv);
552f9f848faSopenharmony_ci			dval(&rv) *= tinytens[j];
553f9f848faSopenharmony_ci			if (!dval(&rv)) {
554f9f848faSopenharmony_ci				dval(&rv) = 2.*dval(&rv0);
555f9f848faSopenharmony_ci				dval(&rv) *= tinytens[j];
556f9f848faSopenharmony_ci#endif
557f9f848faSopenharmony_ci				if (!dval(&rv)) {
558f9f848faSopenharmony_ci undfl:
559f9f848faSopenharmony_ci					dval(&rv) = 0.;
560f9f848faSopenharmony_ci					goto range_err;
561f9f848faSopenharmony_ci					}
562f9f848faSopenharmony_ci#ifndef Avoid_Underflow
563f9f848faSopenharmony_ci				word0(&rv) = Tiny0;
564f9f848faSopenharmony_ci				word1(&rv) = Tiny1;
565f9f848faSopenharmony_ci				/* The refinement below will clean
566f9f848faSopenharmony_ci				 * this approximation up.
567f9f848faSopenharmony_ci				 */
568f9f848faSopenharmony_ci				}
569f9f848faSopenharmony_ci#endif
570f9f848faSopenharmony_ci			}
571f9f848faSopenharmony_ci		}
572f9f848faSopenharmony_ci
573f9f848faSopenharmony_ci	/* Now the hard part -- adjusting rv to the correct value.*/
574f9f848faSopenharmony_ci
575f9f848faSopenharmony_ci	/* Put digits into bd: true value = bd * 10^e */
576f9f848faSopenharmony_ci
577f9f848faSopenharmony_ci	bd0 = s2b(s0, nd0, nd, y, dplen);
578f9f848faSopenharmony_ci
579f9f848faSopenharmony_ci	for(;;) {
580f9f848faSopenharmony_ci		bd = Balloc(bd0->k);
581f9f848faSopenharmony_ci		Bcopy(bd, bd0);
582f9f848faSopenharmony_ci		bb = d2b(dval(&rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
583f9f848faSopenharmony_ci		bs = i2b(1);
584f9f848faSopenharmony_ci
585f9f848faSopenharmony_ci		if (e >= 0) {
586f9f848faSopenharmony_ci			bb2 = bb5 = 0;
587f9f848faSopenharmony_ci			bd2 = bd5 = e;
588f9f848faSopenharmony_ci			}
589f9f848faSopenharmony_ci		else {
590f9f848faSopenharmony_ci			bb2 = bb5 = -e;
591f9f848faSopenharmony_ci			bd2 = bd5 = 0;
592f9f848faSopenharmony_ci			}
593f9f848faSopenharmony_ci		if (bbe >= 0)
594f9f848faSopenharmony_ci			bb2 += bbe;
595f9f848faSopenharmony_ci		else
596f9f848faSopenharmony_ci			bd2 -= bbe;
597f9f848faSopenharmony_ci		bs2 = bb2;
598f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
599f9f848faSopenharmony_ci		if (Rounding != 1)
600f9f848faSopenharmony_ci			bs2++;
601f9f848faSopenharmony_ci#endif
602f9f848faSopenharmony_ci#ifdef Avoid_Underflow
603f9f848faSopenharmony_ci		Lsb = LSB;
604f9f848faSopenharmony_ci		Lsb1 = 0;
605f9f848faSopenharmony_ci		j = bbe - scale;
606f9f848faSopenharmony_ci		i = j + bbbits - 1;	/* logb(rv) */
607f9f848faSopenharmony_ci		j = P + 1 - bbbits;
608f9f848faSopenharmony_ci		if (i < Emin) {	/* denormal */
609f9f848faSopenharmony_ci			i = Emin - i;
610f9f848faSopenharmony_ci			j -= i;
611f9f848faSopenharmony_ci			if (i < 32)
612f9f848faSopenharmony_ci				Lsb <<= i;
613f9f848faSopenharmony_ci			else
614f9f848faSopenharmony_ci				Lsb1 = Lsb << (i-32);
615f9f848faSopenharmony_ci			}
616f9f848faSopenharmony_ci#else /*Avoid_Underflow*/
617f9f848faSopenharmony_ci#ifdef Sudden_Underflow
618f9f848faSopenharmony_ci#ifdef IBM
619f9f848faSopenharmony_ci		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
620f9f848faSopenharmony_ci#else
621f9f848faSopenharmony_ci		j = P + 1 - bbbits;
622f9f848faSopenharmony_ci#endif
623f9f848faSopenharmony_ci#else /*Sudden_Underflow*/
624f9f848faSopenharmony_ci		j = bbe;
625f9f848faSopenharmony_ci		i = j + bbbits - 1;	/* logb(&rv) */
626f9f848faSopenharmony_ci		if (i < Emin)	/* denormal */
627f9f848faSopenharmony_ci			j += P - Emin;
628f9f848faSopenharmony_ci		else
629f9f848faSopenharmony_ci			j = P + 1 - bbbits;
630f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/
631f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
632f9f848faSopenharmony_ci		bb2 += j;
633f9f848faSopenharmony_ci		bd2 += j;
634f9f848faSopenharmony_ci#ifdef Avoid_Underflow
635f9f848faSopenharmony_ci		bd2 += scale;
636f9f848faSopenharmony_ci#endif
637f9f848faSopenharmony_ci		i = bb2 < bd2 ? bb2 : bd2;
638f9f848faSopenharmony_ci		if (i > bs2)
639f9f848faSopenharmony_ci			i = bs2;
640f9f848faSopenharmony_ci		if (i > 0) {
641f9f848faSopenharmony_ci			bb2 -= i;
642f9f848faSopenharmony_ci			bd2 -= i;
643f9f848faSopenharmony_ci			bs2 -= i;
644f9f848faSopenharmony_ci			}
645f9f848faSopenharmony_ci		if (bb5 > 0) {
646f9f848faSopenharmony_ci			bs = pow5mult(bs, bb5);
647f9f848faSopenharmony_ci			bb1 = mult(bs, bb);
648f9f848faSopenharmony_ci			Bfree(bb);
649f9f848faSopenharmony_ci			bb = bb1;
650f9f848faSopenharmony_ci			}
651f9f848faSopenharmony_ci		if (bb2 > 0)
652f9f848faSopenharmony_ci			bb = lshift(bb, bb2);
653f9f848faSopenharmony_ci		if (bd5 > 0)
654f9f848faSopenharmony_ci			bd = pow5mult(bd, bd5);
655f9f848faSopenharmony_ci		if (bd2 > 0)
656f9f848faSopenharmony_ci			bd = lshift(bd, bd2);
657f9f848faSopenharmony_ci		if (bs2 > 0)
658f9f848faSopenharmony_ci			bs = lshift(bs, bs2);
659f9f848faSopenharmony_ci		delta = diff(bb, bd);
660f9f848faSopenharmony_ci		dsign = delta->sign;
661f9f848faSopenharmony_ci		delta->sign = 0;
662f9f848faSopenharmony_ci		i = cmp(delta, bs);
663f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS
664f9f848faSopenharmony_ci		if (Rounding != 1) {
665f9f848faSopenharmony_ci			if (i < 0) {
666f9f848faSopenharmony_ci				/* Error is less than an ulp */
667f9f848faSopenharmony_ci				if (!delta->x[0] && delta->wds <= 1) {
668f9f848faSopenharmony_ci					/* exact */
669f9f848faSopenharmony_ci#ifdef SET_INEXACT
670f9f848faSopenharmony_ci					inexact = 0;
671f9f848faSopenharmony_ci#endif
672f9f848faSopenharmony_ci					break;
673f9f848faSopenharmony_ci					}
674f9f848faSopenharmony_ci				if (Rounding) {
675f9f848faSopenharmony_ci					if (dsign) {
676f9f848faSopenharmony_ci						dval(&adj) = 1.;
677f9f848faSopenharmony_ci						goto apply_adj;
678f9f848faSopenharmony_ci						}
679f9f848faSopenharmony_ci					}
680f9f848faSopenharmony_ci				else if (!dsign) {
681f9f848faSopenharmony_ci					dval(&adj) = -1.;
682f9f848faSopenharmony_ci					if (!word1(&rv)
683f9f848faSopenharmony_ci					 && !(word0(&rv) & Frac_mask)) {
684f9f848faSopenharmony_ci						y = word0(&rv) & Exp_mask;
685f9f848faSopenharmony_ci#ifdef Avoid_Underflow
686f9f848faSopenharmony_ci						if (!scale || y > 2*P*Exp_msk1)
687f9f848faSopenharmony_ci#else
688f9f848faSopenharmony_ci						if (y)
689f9f848faSopenharmony_ci#endif
690f9f848faSopenharmony_ci						  {
691f9f848faSopenharmony_ci						  delta = lshift(delta,Log2P);
692f9f848faSopenharmony_ci						  if (cmp(delta, bs) <= 0)
693f9f848faSopenharmony_ci							dval(&adj) = -0.5;
694f9f848faSopenharmony_ci						  }
695f9f848faSopenharmony_ci						}
696f9f848faSopenharmony_ci apply_adj:
697f9f848faSopenharmony_ci#ifdef Avoid_Underflow
698f9f848faSopenharmony_ci					if (scale && (y = word0(&rv) & Exp_mask)
699f9f848faSopenharmony_ci						<= 2*P*Exp_msk1)
700f9f848faSopenharmony_ci					  word0(&adj) += (2*P+1)*Exp_msk1 - y;
701f9f848faSopenharmony_ci#else
702f9f848faSopenharmony_ci#ifdef Sudden_Underflow
703f9f848faSopenharmony_ci					if ((word0(&rv) & Exp_mask) <=
704f9f848faSopenharmony_ci							P*Exp_msk1) {
705f9f848faSopenharmony_ci						word0(&rv) += P*Exp_msk1;
706f9f848faSopenharmony_ci						dval(&rv) += adj*ulp(&rv);
707f9f848faSopenharmony_ci						word0(&rv) -= P*Exp_msk1;
708f9f848faSopenharmony_ci						}
709f9f848faSopenharmony_ci					else
710f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/
711f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
712f9f848faSopenharmony_ci					dval(&rv) += adj.d*ulp(&rv);
713f9f848faSopenharmony_ci					}
714f9f848faSopenharmony_ci				break;
715f9f848faSopenharmony_ci				}
716f9f848faSopenharmony_ci			dval(&adj) = ratio(delta, bs);
717f9f848faSopenharmony_ci			if (adj.d < 1.)
718f9f848faSopenharmony_ci				dval(&adj) = 1.;
719f9f848faSopenharmony_ci			if (adj.d <= 0x7ffffffe) {
720f9f848faSopenharmony_ci				/* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
721f9f848faSopenharmony_ci				y = adj.d;
722f9f848faSopenharmony_ci				if (y != adj.d) {
723f9f848faSopenharmony_ci					if (!((Rounding>>1) ^ dsign))
724f9f848faSopenharmony_ci						y++;
725f9f848faSopenharmony_ci					dval(&adj) = y;
726f9f848faSopenharmony_ci					}
727f9f848faSopenharmony_ci				}
728f9f848faSopenharmony_ci#ifdef Avoid_Underflow
729f9f848faSopenharmony_ci			if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
730f9f848faSopenharmony_ci				word0(&adj) += (2*P+1)*Exp_msk1 - y;
731f9f848faSopenharmony_ci#else
732f9f848faSopenharmony_ci#ifdef Sudden_Underflow
733f9f848faSopenharmony_ci			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
734f9f848faSopenharmony_ci				word0(&rv) += P*Exp_msk1;
735f9f848faSopenharmony_ci				dval(&adj) *= ulp(&rv);
736f9f848faSopenharmony_ci				if (dsign)
737f9f848faSopenharmony_ci					dval(&rv) += adj;
738f9f848faSopenharmony_ci				else
739f9f848faSopenharmony_ci					dval(&rv) -= adj;
740f9f848faSopenharmony_ci				word0(&rv) -= P*Exp_msk1;
741f9f848faSopenharmony_ci				goto cont;
742f9f848faSopenharmony_ci				}
743f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/
744f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
745f9f848faSopenharmony_ci			dval(&adj) *= ulp(&rv);
746f9f848faSopenharmony_ci			if (dsign) {
747f9f848faSopenharmony_ci				if (word0(&rv) == Big0 && word1(&rv) == Big1)
748f9f848faSopenharmony_ci					goto ovfl;
749f9f848faSopenharmony_ci				dval(&rv) += adj.d;
750f9f848faSopenharmony_ci				}
751f9f848faSopenharmony_ci			else
752f9f848faSopenharmony_ci				dval(&rv) -= adj.d;
753f9f848faSopenharmony_ci			goto cont;
754f9f848faSopenharmony_ci			}
755f9f848faSopenharmony_ci#endif /*Honor_FLT_ROUNDS*/
756f9f848faSopenharmony_ci
757f9f848faSopenharmony_ci		if (i < 0) {
758f9f848faSopenharmony_ci			/* Error is less than half an ulp -- check for
759f9f848faSopenharmony_ci			 * special case of mantissa a power of two.
760f9f848faSopenharmony_ci			 */
761f9f848faSopenharmony_ci			if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
762f9f848faSopenharmony_ci#ifdef IEEE_Arith
763f9f848faSopenharmony_ci#ifdef Avoid_Underflow
764f9f848faSopenharmony_ci			 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
765f9f848faSopenharmony_ci#else
766f9f848faSopenharmony_ci			 || (word0(&rv) & Exp_mask) <= Exp_msk1
767f9f848faSopenharmony_ci#endif
768f9f848faSopenharmony_ci#endif
769f9f848faSopenharmony_ci				) {
770f9f848faSopenharmony_ci#ifdef SET_INEXACT
771f9f848faSopenharmony_ci				if (!delta->x[0] && delta->wds <= 1)
772f9f848faSopenharmony_ci					inexact = 0;
773f9f848faSopenharmony_ci#endif
774f9f848faSopenharmony_ci				break;
775f9f848faSopenharmony_ci				}
776f9f848faSopenharmony_ci			if (!delta->x[0] && delta->wds <= 1) {
777f9f848faSopenharmony_ci				/* exact result */
778f9f848faSopenharmony_ci#ifdef SET_INEXACT
779f9f848faSopenharmony_ci				inexact = 0;
780f9f848faSopenharmony_ci#endif
781f9f848faSopenharmony_ci				break;
782f9f848faSopenharmony_ci				}
783f9f848faSopenharmony_ci			delta = lshift(delta,Log2P);
784f9f848faSopenharmony_ci			if (cmp(delta, bs) > 0)
785f9f848faSopenharmony_ci				goto drop_down;
786f9f848faSopenharmony_ci			break;
787f9f848faSopenharmony_ci			}
788f9f848faSopenharmony_ci		if (i == 0) {
789f9f848faSopenharmony_ci			/* exactly half-way between */
790f9f848faSopenharmony_ci			if (dsign) {
791f9f848faSopenharmony_ci				if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
792f9f848faSopenharmony_ci				 &&  word1(&rv) == (
793f9f848faSopenharmony_ci#ifdef Avoid_Underflow
794f9f848faSopenharmony_ci			(scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1)
795f9f848faSopenharmony_ci		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
796f9f848faSopenharmony_ci#endif
797f9f848faSopenharmony_ci						   0xffffffff)) {
798f9f848faSopenharmony_ci					/*boundary case -- increment exponent*/
799f9f848faSopenharmony_ci					if (word0(&rv) == Big0 && word1(&rv) == Big1)
800f9f848faSopenharmony_ci						goto ovfl;
801f9f848faSopenharmony_ci					word0(&rv) = (word0(&rv) & Exp_mask)
802f9f848faSopenharmony_ci						+ Exp_msk1
803f9f848faSopenharmony_ci#ifdef IBM
804f9f848faSopenharmony_ci						| Exp_msk1 >> 4
805f9f848faSopenharmony_ci#endif
806f9f848faSopenharmony_ci						;
807f9f848faSopenharmony_ci					word1(&rv) = 0;
808f9f848faSopenharmony_ci#ifdef Avoid_Underflow
809f9f848faSopenharmony_ci					dsign = 0;
810f9f848faSopenharmony_ci#endif
811f9f848faSopenharmony_ci					break;
812f9f848faSopenharmony_ci					}
813f9f848faSopenharmony_ci				}
814f9f848faSopenharmony_ci			else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
815f9f848faSopenharmony_ci drop_down:
816f9f848faSopenharmony_ci				/* boundary case -- decrement exponent */
817f9f848faSopenharmony_ci#ifdef Sudden_Underflow /*{{*/
818f9f848faSopenharmony_ci				L = word0(&rv) & Exp_mask;
819f9f848faSopenharmony_ci#ifdef IBM
820f9f848faSopenharmony_ci				if (L <  Exp_msk1)
821f9f848faSopenharmony_ci#else
822f9f848faSopenharmony_ci#ifdef Avoid_Underflow
823f9f848faSopenharmony_ci				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
824f9f848faSopenharmony_ci#else
825f9f848faSopenharmony_ci				if (L <= Exp_msk1)
826f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
827f9f848faSopenharmony_ci#endif /*IBM*/
828f9f848faSopenharmony_ci					goto undfl;
829f9f848faSopenharmony_ci				L -= Exp_msk1;
830f9f848faSopenharmony_ci#else /*Sudden_Underflow}{*/
831f9f848faSopenharmony_ci#ifdef Avoid_Underflow
832f9f848faSopenharmony_ci				if (scale) {
833f9f848faSopenharmony_ci					L = word0(&rv) & Exp_mask;
834f9f848faSopenharmony_ci					if (L <= (2*P+1)*Exp_msk1) {
835f9f848faSopenharmony_ci						if (L > (P+2)*Exp_msk1)
836f9f848faSopenharmony_ci							/* round even ==> */
837f9f848faSopenharmony_ci							/* accept rv */
838f9f848faSopenharmony_ci							break;
839f9f848faSopenharmony_ci						/* rv = smallest denormal */
840f9f848faSopenharmony_ci						goto undfl;
841f9f848faSopenharmony_ci						}
842f9f848faSopenharmony_ci					}
843f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
844f9f848faSopenharmony_ci				L = (word0(&rv) & Exp_mask) - Exp_msk1;
845f9f848faSopenharmony_ci#endif /*Sudden_Underflow}}*/
846f9f848faSopenharmony_ci				word0(&rv) = L | Bndry_mask1;
847f9f848faSopenharmony_ci				word1(&rv) = 0xffffffff;
848f9f848faSopenharmony_ci#ifdef IBM
849f9f848faSopenharmony_ci				goto cont;
850f9f848faSopenharmony_ci#else
851f9f848faSopenharmony_ci				break;
852f9f848faSopenharmony_ci#endif
853f9f848faSopenharmony_ci				}
854f9f848faSopenharmony_ci#ifndef ROUND_BIASED
855f9f848faSopenharmony_ci#ifdef Avoid_Underflow
856f9f848faSopenharmony_ci			if (Lsb1) {
857f9f848faSopenharmony_ci				if (!(word0(&rv) & Lsb1))
858f9f848faSopenharmony_ci					break;
859f9f848faSopenharmony_ci				}
860f9f848faSopenharmony_ci			else if (!(word1(&rv) & Lsb))
861f9f848faSopenharmony_ci				break;
862f9f848faSopenharmony_ci#else
863f9f848faSopenharmony_ci			if (!(word1(&rv) & LSB))
864f9f848faSopenharmony_ci				break;
865f9f848faSopenharmony_ci#endif
866f9f848faSopenharmony_ci#endif
867f9f848faSopenharmony_ci			if (dsign)
868f9f848faSopenharmony_ci#ifdef Avoid_Underflow
869f9f848faSopenharmony_ci				dval(&rv) += sulp(&rv, scale);
870f9f848faSopenharmony_ci#else
871f9f848faSopenharmony_ci				dval(&rv) += ulp(&rv);
872f9f848faSopenharmony_ci#endif
873f9f848faSopenharmony_ci#ifndef ROUND_BIASED
874f9f848faSopenharmony_ci			else {
875f9f848faSopenharmony_ci#ifdef Avoid_Underflow
876f9f848faSopenharmony_ci				dval(&rv) -= sulp(&rv, scale);
877f9f848faSopenharmony_ci#else
878f9f848faSopenharmony_ci				dval(&rv) -= ulp(&rv);
879f9f848faSopenharmony_ci#endif
880f9f848faSopenharmony_ci#ifndef Sudden_Underflow
881f9f848faSopenharmony_ci				if (!dval(&rv))
882f9f848faSopenharmony_ci					goto undfl;
883f9f848faSopenharmony_ci#endif
884f9f848faSopenharmony_ci				}
885f9f848faSopenharmony_ci#ifdef Avoid_Underflow
886f9f848faSopenharmony_ci			dsign = 1 - dsign;
887f9f848faSopenharmony_ci#endif
888f9f848faSopenharmony_ci#endif
889f9f848faSopenharmony_ci			break;
890f9f848faSopenharmony_ci			}
891f9f848faSopenharmony_ci		if ((aadj = ratio(delta, bs)) <= 2.) {
892f9f848faSopenharmony_ci			if (dsign)
893f9f848faSopenharmony_ci				aadj = dval(&aadj1) = 1.;
894f9f848faSopenharmony_ci			else if (word1(&rv) || word0(&rv) & Bndry_mask) {
895f9f848faSopenharmony_ci#ifndef Sudden_Underflow
896f9f848faSopenharmony_ci				if (word1(&rv) == Tiny1 && !word0(&rv))
897f9f848faSopenharmony_ci					goto undfl;
898f9f848faSopenharmony_ci#endif
899f9f848faSopenharmony_ci				aadj = 1.;
900f9f848faSopenharmony_ci				dval(&aadj1) = -1.;
901f9f848faSopenharmony_ci				}
902f9f848faSopenharmony_ci			else {
903f9f848faSopenharmony_ci				/* special case -- power of FLT_RADIX to be */
904f9f848faSopenharmony_ci				/* rounded down... */
905f9f848faSopenharmony_ci
906f9f848faSopenharmony_ci				if (aadj < 2./FLT_RADIX)
907f9f848faSopenharmony_ci					aadj = 1./FLT_RADIX;
908f9f848faSopenharmony_ci				else
909f9f848faSopenharmony_ci					aadj *= 0.5;
910f9f848faSopenharmony_ci				dval(&aadj1) = -aadj;
911f9f848faSopenharmony_ci				}
912f9f848faSopenharmony_ci			}
913f9f848faSopenharmony_ci		else {
914f9f848faSopenharmony_ci			aadj *= 0.5;
915f9f848faSopenharmony_ci			dval(&aadj1) = dsign ? aadj : -aadj;
916f9f848faSopenharmony_ci#ifdef Check_FLT_ROUNDS
917f9f848faSopenharmony_ci			switch(Rounding) {
918f9f848faSopenharmony_ci				case 2: /* towards +infinity */
919f9f848faSopenharmony_ci					dval(&aadj1) -= 0.5;
920f9f848faSopenharmony_ci					break;
921f9f848faSopenharmony_ci				case 0: /* towards 0 */
922f9f848faSopenharmony_ci				case 3: /* towards -infinity */
923f9f848faSopenharmony_ci					dval(&aadj1) += 0.5;
924f9f848faSopenharmony_ci				}
925f9f848faSopenharmony_ci#else
926f9f848faSopenharmony_ci			if (Flt_Rounds == 0)
927f9f848faSopenharmony_ci				dval(&aadj1) += 0.5;
928f9f848faSopenharmony_ci#endif /*Check_FLT_ROUNDS*/
929f9f848faSopenharmony_ci			}
930f9f848faSopenharmony_ci		y = word0(&rv) & Exp_mask;
931f9f848faSopenharmony_ci
932f9f848faSopenharmony_ci		/* Check for overflow */
933f9f848faSopenharmony_ci
934f9f848faSopenharmony_ci		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
935f9f848faSopenharmony_ci			dval(&rv0) = dval(&rv);
936f9f848faSopenharmony_ci			word0(&rv) -= P*Exp_msk1;
937f9f848faSopenharmony_ci			dval(&adj) = dval(&aadj1) * ulp(&rv);
938f9f848faSopenharmony_ci			dval(&rv) += dval(&adj);
939f9f848faSopenharmony_ci			if ((word0(&rv) & Exp_mask) >=
940f9f848faSopenharmony_ci					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
941f9f848faSopenharmony_ci				if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
942f9f848faSopenharmony_ci					goto ovfl;
943f9f848faSopenharmony_ci				word0(&rv) = Big0;
944f9f848faSopenharmony_ci				word1(&rv) = Big1;
945f9f848faSopenharmony_ci				goto cont;
946f9f848faSopenharmony_ci				}
947f9f848faSopenharmony_ci			else
948f9f848faSopenharmony_ci				word0(&rv) += P*Exp_msk1;
949f9f848faSopenharmony_ci			}
950f9f848faSopenharmony_ci		else {
951f9f848faSopenharmony_ci#ifdef Avoid_Underflow
952f9f848faSopenharmony_ci			if (scale && y <= 2*P*Exp_msk1) {
953f9f848faSopenharmony_ci				if (aadj <= 0x7fffffff) {
954f9f848faSopenharmony_ci					if ((z = aadj) <= 0)
955f9f848faSopenharmony_ci						z = 1;
956f9f848faSopenharmony_ci					aadj = z;
957f9f848faSopenharmony_ci					dval(&aadj1) = dsign ? aadj : -aadj;
958f9f848faSopenharmony_ci					}
959f9f848faSopenharmony_ci				word0(&aadj1) += (2*P+1)*Exp_msk1 - y;
960f9f848faSopenharmony_ci				}
961f9f848faSopenharmony_ci			dval(&adj) = dval(&aadj1) * ulp(&rv);
962f9f848faSopenharmony_ci			dval(&rv) += dval(&adj);
963f9f848faSopenharmony_ci#else
964f9f848faSopenharmony_ci#ifdef Sudden_Underflow
965f9f848faSopenharmony_ci			if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
966f9f848faSopenharmony_ci				dval(&rv0) = dval(&rv);
967f9f848faSopenharmony_ci				word0(&rv) += P*Exp_msk1;
968f9f848faSopenharmony_ci				dval(&adj) = dval(&aadj1) * ulp(&rv);
969f9f848faSopenharmony_ci				dval(&rv) += adj;
970f9f848faSopenharmony_ci#ifdef IBM
971f9f848faSopenharmony_ci				if ((word0(&rv) & Exp_mask) <  P*Exp_msk1)
972f9f848faSopenharmony_ci#else
973f9f848faSopenharmony_ci				if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
974f9f848faSopenharmony_ci#endif
975f9f848faSopenharmony_ci					{
976f9f848faSopenharmony_ci					if (word0(&rv0) == Tiny0
977f9f848faSopenharmony_ci					 && word1(&rv0) == Tiny1)
978f9f848faSopenharmony_ci						goto undfl;
979f9f848faSopenharmony_ci					word0(&rv) = Tiny0;
980f9f848faSopenharmony_ci					word1(&rv) = Tiny1;
981f9f848faSopenharmony_ci					goto cont;
982f9f848faSopenharmony_ci					}
983f9f848faSopenharmony_ci				else
984f9f848faSopenharmony_ci					word0(&rv) -= P*Exp_msk1;
985f9f848faSopenharmony_ci				}
986f9f848faSopenharmony_ci			else {
987f9f848faSopenharmony_ci				dval(&adj) = dval(&aadj1) * ulp(&rv);
988f9f848faSopenharmony_ci				dval(&rv) += adj;
989f9f848faSopenharmony_ci				}
990f9f848faSopenharmony_ci#else /*Sudden_Underflow*/
991f9f848faSopenharmony_ci			/* Compute dval(&adj) so that the IEEE rounding rules will
992f9f848faSopenharmony_ci			 * correctly round rv + dval(&adj) in some half-way cases.
993f9f848faSopenharmony_ci			 * If rv * ulp(&rv) is denormalized (i.e.,
994f9f848faSopenharmony_ci			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
995f9f848faSopenharmony_ci			 * trouble from bits lost to denormalization;
996f9f848faSopenharmony_ci			 * example: 1.2e-307 .
997f9f848faSopenharmony_ci			 */
998f9f848faSopenharmony_ci			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
999f9f848faSopenharmony_ci				dval(&aadj1) = (double)(int)(aadj + 0.5);
1000f9f848faSopenharmony_ci				if (!dsign)
1001f9f848faSopenharmony_ci					dval(&aadj1) = -dval(&aadj1);
1002f9f848faSopenharmony_ci				}
1003f9f848faSopenharmony_ci			dval(&adj) = dval(&aadj1) * ulp(&rv);
1004f9f848faSopenharmony_ci			dval(&rv) += adj;
1005f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/
1006f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/
1007f9f848faSopenharmony_ci			}
1008f9f848faSopenharmony_ci		z = word0(&rv) & Exp_mask;
1009f9f848faSopenharmony_ci#ifndef SET_INEXACT
1010f9f848faSopenharmony_ci#ifdef Avoid_Underflow
1011f9f848faSopenharmony_ci		if (!scale)
1012f9f848faSopenharmony_ci#endif
1013f9f848faSopenharmony_ci		if (y == z) {
1014f9f848faSopenharmony_ci			/* Can we stop now? */
1015f9f848faSopenharmony_ci			L = (Long)aadj;
1016f9f848faSopenharmony_ci			aadj -= L;
1017f9f848faSopenharmony_ci			/* The tolerances below are conservative. */
1018f9f848faSopenharmony_ci			if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
1019f9f848faSopenharmony_ci				if (aadj < .4999999 || aadj > .5000001)
1020f9f848faSopenharmony_ci					break;
1021f9f848faSopenharmony_ci				}
1022f9f848faSopenharmony_ci			else if (aadj < .4999999/FLT_RADIX)
1023f9f848faSopenharmony_ci				break;
1024f9f848faSopenharmony_ci			}
1025f9f848faSopenharmony_ci#endif
1026f9f848faSopenharmony_ci cont:
1027f9f848faSopenharmony_ci		Bfree(bb);
1028f9f848faSopenharmony_ci		Bfree(bd);
1029f9f848faSopenharmony_ci		Bfree(bs);
1030f9f848faSopenharmony_ci		Bfree(delta);
1031f9f848faSopenharmony_ci		}
1032f9f848faSopenharmony_ci	Bfree(bb);
1033f9f848faSopenharmony_ci	Bfree(bd);
1034f9f848faSopenharmony_ci	Bfree(bs);
1035f9f848faSopenharmony_ci	Bfree(bd0);
1036f9f848faSopenharmony_ci	Bfree(delta);
1037f9f848faSopenharmony_ci#ifdef SET_INEXACT
1038f9f848faSopenharmony_ci	if (inexact) {
1039f9f848faSopenharmony_ci		if (!oldinexact) {
1040f9f848faSopenharmony_ci			word0(&rv0) = Exp_1 + (70 << Exp_shift);
1041f9f848faSopenharmony_ci			word1(&rv0) = 0;
1042f9f848faSopenharmony_ci			dval(&rv0) += 1.;
1043f9f848faSopenharmony_ci			}
1044f9f848faSopenharmony_ci		}
1045f9f848faSopenharmony_ci	else if (!oldinexact)
1046f9f848faSopenharmony_ci		clear_inexact();
1047f9f848faSopenharmony_ci#endif
1048f9f848faSopenharmony_ci#ifdef Avoid_Underflow
1049f9f848faSopenharmony_ci	if (scale) {
1050f9f848faSopenharmony_ci		word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
1051f9f848faSopenharmony_ci		word1(&rv0) = 0;
1052f9f848faSopenharmony_ci		dval(&rv) *= dval(&rv0);
1053f9f848faSopenharmony_ci#ifndef NO_ERRNO
1054f9f848faSopenharmony_ci		/* try to avoid the bug of testing an 8087 register value */
1055f9f848faSopenharmony_ci#ifdef IEEE_Arith
1056f9f848faSopenharmony_ci		if (!(word0(&rv) & Exp_mask))
1057f9f848faSopenharmony_ci#else
1058f9f848faSopenharmony_ci		if (word0(&rv) == 0 && word1(&rv) == 0)
1059f9f848faSopenharmony_ci#endif
1060f9f848faSopenharmony_ci			errno = ERANGE;
1061f9f848faSopenharmony_ci#endif
1062f9f848faSopenharmony_ci		}
1063f9f848faSopenharmony_ci#endif /* Avoid_Underflow */
1064f9f848faSopenharmony_ci#ifdef SET_INEXACT
1065f9f848faSopenharmony_ci	if (inexact && !(word0(&rv) & Exp_mask)) {
1066f9f848faSopenharmony_ci		/* set underflow bit */
1067f9f848faSopenharmony_ci		dval(&rv0) = 1e-300;
1068f9f848faSopenharmony_ci		dval(&rv0) *= dval(&rv0);
1069f9f848faSopenharmony_ci		}
1070f9f848faSopenharmony_ci#endif
1071f9f848faSopenharmony_ci ret:
1072f9f848faSopenharmony_ci	if (se)
1073f9f848faSopenharmony_ci		*se = (char *)s;
1074f9f848faSopenharmony_ci	return sign ? -dval(&rv) : dval(&rv);
1075f9f848faSopenharmony_ci	}
1076f9f848faSopenharmony_ci
1077f9f848faSopenharmony_ci double
1078f9f848faSopenharmony_cistrtod
1079f9f848faSopenharmony_ci#ifdef KR_headers
1080f9f848faSopenharmony_ci	(s00, se, loc) CONST char *s00; char **se; locale_t
1081f9f848faSopenharmony_ci#else
1082f9f848faSopenharmony_ci	(CONST char *s00, char **se)
1083f9f848faSopenharmony_ci#endif
1084f9f848faSopenharmony_ci{
1085f9f848faSopenharmony_ci	return strtod_l(s00, se, 0);
1086f9f848faSopenharmony_ci}
1087f9f848faSopenharmony_ci
1088