strtodg.c revision 1.3 1 1.3 kleink /* $NetBSD: strtodg.c,v 1.3 2006/03/11 18:38:14 kleink Exp $ */
2 1.1 kleink
3 1.1 kleink /****************************************************************
4 1.1 kleink
5 1.1 kleink The author of this software is David M. Gay.
6 1.1 kleink
7 1.1 kleink Copyright (C) 1998-2001 by Lucent Technologies
8 1.1 kleink All Rights Reserved
9 1.1 kleink
10 1.1 kleink Permission to use, copy, modify, and distribute this software and
11 1.1 kleink its documentation for any purpose and without fee is hereby
12 1.1 kleink granted, provided that the above copyright notice appear in all
13 1.1 kleink copies and that both that the copyright notice and this
14 1.1 kleink permission notice and warranty disclaimer appear in supporting
15 1.1 kleink documentation, and that the name of Lucent or any of its entities
16 1.1 kleink not be used in advertising or publicity pertaining to
17 1.1 kleink distribution of the software without specific, written prior
18 1.1 kleink permission.
19 1.1 kleink
20 1.1 kleink LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 1.1 kleink INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 1.1 kleink IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 1.1 kleink SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 1.1 kleink WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 1.1 kleink IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 1.1 kleink ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 1.1 kleink THIS SOFTWARE.
28 1.1 kleink
29 1.1 kleink ****************************************************************/
30 1.1 kleink
31 1.1 kleink /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 1.1 kleink * with " at " changed at "@" and " dot " changed to "."). */
33 1.1 kleink
34 1.1 kleink #include "gdtoaimp.h"
35 1.1 kleink
36 1.1 kleink #ifdef USE_LOCALE
37 1.1 kleink #include "locale.h"
38 1.1 kleink #endif
39 1.1 kleink
40 1.1 kleink static CONST int
41 1.1 kleink fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
42 1.1 kleink 24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
43 1.1 kleink 47, 49, 52
44 1.1 kleink #ifdef VAX
45 1.1 kleink , 54, 56
46 1.1 kleink #endif
47 1.1 kleink };
48 1.1 kleink
49 1.1 kleink Bigint *
50 1.1 kleink #ifdef KR_headers
51 1.1 kleink increment(b) Bigint *b;
52 1.1 kleink #else
53 1.1 kleink increment(Bigint *b)
54 1.1 kleink #endif
55 1.1 kleink {
56 1.1 kleink ULong *x, *xe;
57 1.1 kleink Bigint *b1;
58 1.1 kleink #ifdef Pack_16
59 1.1 kleink ULong carry = 1, y;
60 1.1 kleink #endif
61 1.1 kleink
62 1.1 kleink x = b->x;
63 1.1 kleink xe = x + b->wds;
64 1.1 kleink #ifdef Pack_32
65 1.1 kleink do {
66 1.1 kleink if (*x < (ULong)0xffffffffL) {
67 1.1 kleink ++*x;
68 1.1 kleink return b;
69 1.1 kleink }
70 1.1 kleink *x++ = 0;
71 1.1 kleink } while(x < xe);
72 1.1 kleink #else
73 1.1 kleink do {
74 1.1 kleink y = *x + carry;
75 1.1 kleink carry = y >> 16;
76 1.1 kleink *x++ = y & 0xffff;
77 1.1 kleink if (!carry)
78 1.1 kleink return b;
79 1.1 kleink } while(x < xe);
80 1.1 kleink if (carry)
81 1.1 kleink #endif
82 1.1 kleink {
83 1.1 kleink if (b->wds >= b->maxwds) {
84 1.1 kleink b1 = Balloc(b->k+1);
85 1.1 kleink Bcopy(b1,b);
86 1.1 kleink Bfree(b);
87 1.1 kleink b = b1;
88 1.1 kleink }
89 1.1 kleink b->x[b->wds++] = 1;
90 1.1 kleink }
91 1.1 kleink return b;
92 1.1 kleink }
93 1.1 kleink
94 1.1 kleink int
95 1.1 kleink #ifdef KR_headers
96 1.1 kleink decrement(b) Bigint *b;
97 1.1 kleink #else
98 1.1 kleink decrement(Bigint *b)
99 1.1 kleink #endif
100 1.1 kleink {
101 1.1 kleink ULong *x, *xe;
102 1.1 kleink #ifdef Pack_16
103 1.1 kleink ULong borrow = 1, y;
104 1.1 kleink #endif
105 1.1 kleink
106 1.1 kleink x = b->x;
107 1.1 kleink xe = x + b->wds;
108 1.1 kleink #ifdef Pack_32
109 1.1 kleink do {
110 1.1 kleink if (*x) {
111 1.1 kleink --*x;
112 1.1 kleink break;
113 1.1 kleink }
114 1.2 kleink *x++ = 0xffffffffUL;
115 1.1 kleink }
116 1.1 kleink while(x < xe);
117 1.1 kleink #else
118 1.1 kleink do {
119 1.1 kleink y = *x - borrow;
120 1.1 kleink borrow = (y & 0x10000) >> 16;
121 1.1 kleink *x++ = y & 0xffff;
122 1.1 kleink } while(borrow && x < xe);
123 1.1 kleink #endif
124 1.1 kleink return STRTOG_Inexlo;
125 1.1 kleink }
126 1.1 kleink
127 1.1 kleink static int
128 1.1 kleink #ifdef KR_headers
129 1.3 kleink all_on(b, n) CONST Bigint *b; int n;
130 1.1 kleink #else
131 1.3 kleink all_on(CONST Bigint *b, int n)
132 1.1 kleink #endif
133 1.1 kleink {
134 1.3 kleink CONST ULong *x, *xe;
135 1.1 kleink
136 1.1 kleink x = b->x;
137 1.2 kleink xe = x + ((unsigned int)n >> kshift);
138 1.1 kleink while(x < xe)
139 1.1 kleink if ((*x++ & ALL_ON) != ALL_ON)
140 1.1 kleink return 0;
141 1.1 kleink if (n &= kmask)
142 1.1 kleink return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON;
143 1.1 kleink return 1;
144 1.1 kleink }
145 1.1 kleink
146 1.1 kleink Bigint *
147 1.1 kleink #ifdef KR_headers
148 1.1 kleink set_ones(b, n) Bigint *b; int n;
149 1.1 kleink #else
150 1.1 kleink set_ones(Bigint *b, int n)
151 1.1 kleink #endif
152 1.1 kleink {
153 1.1 kleink int k;
154 1.1 kleink ULong *x, *xe;
155 1.1 kleink
156 1.2 kleink k = (unsigned int)(n + ((1 << kshift) - 1)) >> kshift;
157 1.1 kleink if (b->k < k) {
158 1.1 kleink Bfree(b);
159 1.1 kleink b = Balloc(k);
160 1.1 kleink }
161 1.2 kleink k = (unsigned int)n >> kshift;
162 1.1 kleink if (n &= kmask)
163 1.1 kleink k++;
164 1.1 kleink b->wds = k;
165 1.1 kleink x = b->x;
166 1.1 kleink xe = x + k;
167 1.1 kleink while(x < xe)
168 1.1 kleink *x++ = ALL_ON;
169 1.1 kleink if (n)
170 1.1 kleink x[-1] >>= ULbits - n;
171 1.1 kleink return b;
172 1.1 kleink }
173 1.1 kleink
174 1.1 kleink static int
175 1.1 kleink rvOK
176 1.1 kleink #ifdef KR_headers
177 1.2 kleink (d, fpi, expt, bits, exact, rd, irv)
178 1.3 kleink double d; CONST FPI *fpi; Long *expt; ULong *bits; int exact, rd, *irv;
179 1.1 kleink #else
180 1.3 kleink (double d, CONST FPI *fpi, Long *expt, ULong *bits, int exact, int rd, int *irv)
181 1.1 kleink #endif
182 1.1 kleink {
183 1.1 kleink Bigint *b;
184 1.1 kleink ULong carry, inex, lostbits;
185 1.1 kleink int bdif, e, j, k, k1, nb, rv;
186 1.1 kleink
187 1.1 kleink carry = rv = 0;
188 1.1 kleink b = d2b(d, &e, &bdif);
189 1.1 kleink bdif -= nb = fpi->nbits;
190 1.1 kleink e += bdif;
191 1.1 kleink if (bdif <= 0) {
192 1.1 kleink if (exact)
193 1.1 kleink goto trunc;
194 1.1 kleink goto ret;
195 1.1 kleink }
196 1.1 kleink if (P == nb) {
197 1.1 kleink if (
198 1.1 kleink #ifndef IMPRECISE_INEXACT
199 1.1 kleink exact &&
200 1.1 kleink #endif
201 1.1 kleink fpi->rounding ==
202 1.1 kleink #ifdef RND_PRODQUOT
203 1.1 kleink FPI_Round_near
204 1.1 kleink #else
205 1.1 kleink Flt_Rounds
206 1.1 kleink #endif
207 1.1 kleink ) goto trunc;
208 1.1 kleink goto ret;
209 1.1 kleink }
210 1.1 kleink switch(rd) {
211 1.1 kleink case 1:
212 1.1 kleink goto trunc;
213 1.1 kleink case 2:
214 1.1 kleink break;
215 1.1 kleink default: /* round near */
216 1.1 kleink k = bdif - 1;
217 1.1 kleink if (k < 0)
218 1.1 kleink goto trunc;
219 1.1 kleink if (!k) {
220 1.1 kleink if (!exact)
221 1.1 kleink goto ret;
222 1.1 kleink if (b->x[0] & 2)
223 1.1 kleink break;
224 1.1 kleink goto trunc;
225 1.1 kleink }
226 1.2 kleink if (b->x[(unsigned int)k>>kshift] & ((ULong)1 << (k & kmask)))
227 1.1 kleink break;
228 1.1 kleink goto trunc;
229 1.1 kleink }
230 1.1 kleink /* "break" cases: round up 1 bit, then truncate; bdif > 0 */
231 1.1 kleink carry = 1;
232 1.1 kleink trunc:
233 1.1 kleink inex = lostbits = 0;
234 1.1 kleink if (bdif > 0) {
235 1.1 kleink if ( (lostbits = any_on(b, bdif)) !=0)
236 1.1 kleink inex = STRTOG_Inexlo;
237 1.1 kleink rshift(b, bdif);
238 1.1 kleink if (carry) {
239 1.1 kleink inex = STRTOG_Inexhi;
240 1.1 kleink b = increment(b);
241 1.1 kleink if ( (j = nb & kmask) !=0)
242 1.1 kleink j = ULbits - j;
243 1.1 kleink if (hi0bits(b->x[b->wds - 1]) != j) {
244 1.1 kleink if (!lostbits)
245 1.1 kleink lostbits = b->x[0] & 1;
246 1.1 kleink rshift(b, 1);
247 1.1 kleink e++;
248 1.1 kleink }
249 1.1 kleink }
250 1.1 kleink }
251 1.1 kleink else if (bdif < 0)
252 1.1 kleink b = lshift(b, -bdif);
253 1.1 kleink if (e < fpi->emin) {
254 1.1 kleink k = fpi->emin - e;
255 1.1 kleink e = fpi->emin;
256 1.1 kleink if (k > nb || fpi->sudden_underflow) {
257 1.1 kleink b->wds = inex = 0;
258 1.1 kleink *irv = STRTOG_Underflow | STRTOG_Inexlo;
259 1.1 kleink }
260 1.1 kleink else {
261 1.1 kleink k1 = k - 1;
262 1.1 kleink if (k1 > 0 && !lostbits)
263 1.1 kleink lostbits = any_on(b, k1);
264 1.1 kleink if (!lostbits && !exact)
265 1.1 kleink goto ret;
266 1.1 kleink lostbits |=
267 1.2 kleink carry = b->x[(unsigned int)k1>>kshift] &
268 1.2 kleink (1 << (k1 & kmask));
269 1.1 kleink rshift(b, k);
270 1.1 kleink *irv = STRTOG_Denormal;
271 1.1 kleink if (carry) {
272 1.1 kleink b = increment(b);
273 1.1 kleink inex = STRTOG_Inexhi | STRTOG_Underflow;
274 1.1 kleink }
275 1.1 kleink else if (lostbits)
276 1.1 kleink inex = STRTOG_Inexlo | STRTOG_Underflow;
277 1.1 kleink }
278 1.1 kleink }
279 1.1 kleink else if (e > fpi->emax) {
280 1.1 kleink e = fpi->emax + 1;
281 1.1 kleink *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
282 1.1 kleink #ifndef NO_ERRNO
283 1.1 kleink errno = ERANGE;
284 1.1 kleink #endif
285 1.1 kleink b->wds = inex = 0;
286 1.1 kleink }
287 1.2 kleink *expt = e;
288 1.1 kleink copybits(bits, nb, b);
289 1.1 kleink *irv |= inex;
290 1.1 kleink rv = 1;
291 1.1 kleink ret:
292 1.1 kleink Bfree(b);
293 1.1 kleink return rv;
294 1.1 kleink }
295 1.1 kleink
296 1.2 kleink #ifndef VAX
297 1.1 kleink static int
298 1.1 kleink #ifdef KR_headers
299 1.1 kleink mantbits(d) double d;
300 1.1 kleink #else
301 1.1 kleink mantbits(double d)
302 1.1 kleink #endif
303 1.1 kleink {
304 1.1 kleink ULong L;
305 1.1 kleink #ifdef VAX
306 1.1 kleink L = word1(d) << 16 | word1(d) >> 16;
307 1.1 kleink if (L)
308 1.1 kleink #else
309 1.1 kleink if ( (L = word1(d)) !=0)
310 1.1 kleink #endif
311 1.1 kleink return P - lo0bits(&L);
312 1.1 kleink #ifdef VAX
313 1.1 kleink L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11;
314 1.1 kleink #else
315 1.1 kleink L = word0(d) | Exp_msk1;
316 1.1 kleink #endif
317 1.1 kleink return P - 32 - lo0bits(&L);
318 1.1 kleink }
319 1.2 kleink #endif /* !VAX */
320 1.1 kleink
321 1.1 kleink int
322 1.1 kleink strtodg
323 1.1 kleink #ifdef KR_headers
324 1.2 kleink (s00, se, fpi, expt, bits)
325 1.3 kleink CONST char *s00; char **se; CONST FPI *fpi; Long *expt; ULong *bits;
326 1.1 kleink #else
327 1.3 kleink (CONST char *s00, char **se, CONST FPI *fpi, Long *expt, ULong *bits)
328 1.1 kleink #endif
329 1.1 kleink {
330 1.1 kleink int abe, abits, asub;
331 1.1 kleink int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;
332 1.1 kleink int dsign, e, e1, e2, emin, esign, finished, i, inex, irv;
333 1.1 kleink int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
334 1.2 kleink int sudden_underflow = 0; /* pacify gcc */
335 1.1 kleink CONST char *s, *s0, *s1;
336 1.1 kleink double adj, adj0, rv, tol;
337 1.1 kleink Long L;
338 1.1 kleink ULong y, z;
339 1.1 kleink Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
340 1.1 kleink
341 1.1 kleink irv = STRTOG_Zero;
342 1.1 kleink denorm = sign = nz0 = nz = 0;
343 1.1 kleink dval(rv) = 0.;
344 1.1 kleink rvb = 0;
345 1.1 kleink nbits = fpi->nbits;
346 1.1 kleink for(s = s00;;s++) switch(*s) {
347 1.1 kleink case '-':
348 1.1 kleink sign = 1;
349 1.2 kleink /* FALLTHROUGH */
350 1.1 kleink case '+':
351 1.1 kleink if (*++s)
352 1.1 kleink goto break2;
353 1.2 kleink /* FALLTHROUGH */
354 1.1 kleink case 0:
355 1.1 kleink sign = 0;
356 1.1 kleink irv = STRTOG_NoNumber;
357 1.1 kleink s = s00;
358 1.1 kleink goto ret;
359 1.1 kleink case '\t':
360 1.1 kleink case '\n':
361 1.1 kleink case '\v':
362 1.1 kleink case '\f':
363 1.1 kleink case '\r':
364 1.1 kleink case ' ':
365 1.1 kleink continue;
366 1.1 kleink default:
367 1.1 kleink goto break2;
368 1.1 kleink }
369 1.1 kleink break2:
370 1.1 kleink if (*s == '0') {
371 1.1 kleink #ifndef NO_HEX_FP
372 1.1 kleink switch(s[1]) {
373 1.1 kleink case 'x':
374 1.1 kleink case 'X':
375 1.2 kleink irv = gethex(&s, fpi, expt, &rvb, sign);
376 1.1 kleink if (irv == STRTOG_NoNumber) {
377 1.1 kleink s = s00;
378 1.1 kleink sign = 0;
379 1.1 kleink }
380 1.1 kleink goto ret;
381 1.1 kleink }
382 1.1 kleink #endif
383 1.1 kleink nz0 = 1;
384 1.1 kleink while(*++s == '0') ;
385 1.1 kleink if (!*s)
386 1.1 kleink goto ret;
387 1.1 kleink }
388 1.1 kleink sudden_underflow = fpi->sudden_underflow;
389 1.1 kleink s0 = s;
390 1.1 kleink y = z = 0;
391 1.1 kleink for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
392 1.1 kleink if (nd < 9)
393 1.1 kleink y = 10*y + c - '0';
394 1.1 kleink else if (nd < 16)
395 1.1 kleink z = 10*z + c - '0';
396 1.1 kleink nd0 = nd;
397 1.1 kleink #ifdef USE_LOCALE
398 1.1 kleink if (c == *localeconv()->decimal_point)
399 1.1 kleink #else
400 1.1 kleink if (c == '.')
401 1.1 kleink #endif
402 1.1 kleink {
403 1.1 kleink decpt = 1;
404 1.1 kleink c = *++s;
405 1.1 kleink if (!nd) {
406 1.1 kleink for(; c == '0'; c = *++s)
407 1.1 kleink nz++;
408 1.1 kleink if (c > '0' && c <= '9') {
409 1.1 kleink s0 = s;
410 1.1 kleink nf += nz;
411 1.1 kleink nz = 0;
412 1.1 kleink goto have_dig;
413 1.1 kleink }
414 1.1 kleink goto dig_done;
415 1.1 kleink }
416 1.1 kleink for(; c >= '0' && c <= '9'; c = *++s) {
417 1.1 kleink have_dig:
418 1.1 kleink nz++;
419 1.1 kleink if (c -= '0') {
420 1.1 kleink nf += nz;
421 1.1 kleink for(i = 1; i < nz; i++)
422 1.1 kleink if (nd++ < 9)
423 1.1 kleink y *= 10;
424 1.1 kleink else if (nd <= DBL_DIG + 1)
425 1.1 kleink z *= 10;
426 1.1 kleink if (nd++ < 9)
427 1.1 kleink y = 10*y + c;
428 1.1 kleink else if (nd <= DBL_DIG + 1)
429 1.1 kleink z = 10*z + c;
430 1.1 kleink nz = 0;
431 1.1 kleink }
432 1.1 kleink }
433 1.1 kleink }
434 1.1 kleink dig_done:
435 1.1 kleink e = 0;
436 1.1 kleink if (c == 'e' || c == 'E') {
437 1.1 kleink if (!nd && !nz && !nz0) {
438 1.1 kleink irv = STRTOG_NoNumber;
439 1.1 kleink s = s00;
440 1.1 kleink goto ret;
441 1.1 kleink }
442 1.1 kleink s00 = s;
443 1.1 kleink esign = 0;
444 1.1 kleink switch(c = *++s) {
445 1.1 kleink case '-':
446 1.1 kleink esign = 1;
447 1.2 kleink /* FALLTHROUGH */
448 1.1 kleink case '+':
449 1.1 kleink c = *++s;
450 1.1 kleink }
451 1.1 kleink if (c >= '0' && c <= '9') {
452 1.1 kleink while(c == '0')
453 1.1 kleink c = *++s;
454 1.1 kleink if (c > '0' && c <= '9') {
455 1.1 kleink L = c - '0';
456 1.1 kleink s1 = s;
457 1.1 kleink while((c = *++s) >= '0' && c <= '9')
458 1.1 kleink L = 10*L + c - '0';
459 1.1 kleink if (s - s1 > 8 || L > 19999)
460 1.1 kleink /* Avoid confusion from exponents
461 1.1 kleink * so large that e might overflow.
462 1.1 kleink */
463 1.1 kleink e = 19999; /* safe for 16 bit ints */
464 1.1 kleink else
465 1.1 kleink e = (int)L;
466 1.1 kleink if (esign)
467 1.1 kleink e = -e;
468 1.1 kleink }
469 1.1 kleink else
470 1.1 kleink e = 0;
471 1.1 kleink }
472 1.1 kleink else
473 1.1 kleink s = s00;
474 1.1 kleink }
475 1.1 kleink if (!nd) {
476 1.1 kleink if (!nz && !nz0) {
477 1.1 kleink #ifdef INFNAN_CHECK
478 1.1 kleink /* Check for Nan and Infinity */
479 1.1 kleink if (!decpt)
480 1.1 kleink switch(c) {
481 1.1 kleink case 'i':
482 1.1 kleink case 'I':
483 1.1 kleink if (match(&s,"nf")) {
484 1.1 kleink --s;
485 1.1 kleink if (!match(&s,"inity"))
486 1.1 kleink ++s;
487 1.1 kleink irv = STRTOG_Infinite;
488 1.1 kleink goto infnanexp;
489 1.1 kleink }
490 1.1 kleink break;
491 1.1 kleink case 'n':
492 1.1 kleink case 'N':
493 1.1 kleink if (match(&s, "an")) {
494 1.1 kleink irv = STRTOG_NaN;
495 1.2 kleink *expt = fpi->emax + 1;
496 1.1 kleink #ifndef No_Hex_NaN
497 1.1 kleink if (*s == '(') /*)*/
498 1.1 kleink irv = hexnan(&s, fpi, bits);
499 1.1 kleink #endif
500 1.1 kleink goto infnanexp;
501 1.1 kleink }
502 1.1 kleink }
503 1.1 kleink #endif /* INFNAN_CHECK */
504 1.1 kleink irv = STRTOG_NoNumber;
505 1.1 kleink s = s00;
506 1.1 kleink }
507 1.1 kleink goto ret;
508 1.1 kleink }
509 1.1 kleink
510 1.1 kleink irv = STRTOG_Normal;
511 1.1 kleink e1 = e -= nf;
512 1.1 kleink rd = 0;
513 1.1 kleink switch(fpi->rounding & 3) {
514 1.1 kleink case FPI_Round_up:
515 1.1 kleink rd = 2 - sign;
516 1.1 kleink break;
517 1.1 kleink case FPI_Round_zero:
518 1.1 kleink rd = 1;
519 1.1 kleink break;
520 1.1 kleink case FPI_Round_down:
521 1.1 kleink rd = 1 + sign;
522 1.1 kleink }
523 1.1 kleink
524 1.1 kleink /* Now we have nd0 digits, starting at s0, followed by a
525 1.1 kleink * decimal point, followed by nd-nd0 digits. The number we're
526 1.1 kleink * after is the integer represented by those digits times
527 1.1 kleink * 10**e */
528 1.1 kleink
529 1.1 kleink if (!nd0)
530 1.1 kleink nd0 = nd;
531 1.1 kleink k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
532 1.1 kleink dval(rv) = y;
533 1.1 kleink if (k > 9)
534 1.1 kleink dval(rv) = tens[k - 9] * dval(rv) + z;
535 1.1 kleink bd0 = 0;
536 1.1 kleink if (nbits <= P && nd <= DBL_DIG) {
537 1.1 kleink if (!e) {
538 1.2 kleink if (rvOK(dval(rv), fpi, expt, bits, 1, rd, &irv))
539 1.1 kleink goto ret;
540 1.1 kleink }
541 1.1 kleink else if (e > 0) {
542 1.1 kleink if (e <= Ten_pmax) {
543 1.1 kleink #ifdef VAX
544 1.1 kleink goto vax_ovfl_check;
545 1.1 kleink #else
546 1.1 kleink i = fivesbits[e] + mantbits(dval(rv)) <= P;
547 1.1 kleink /* rv = */ rounded_product(dval(rv), tens[e]);
548 1.2 kleink if (rvOK(dval(rv), fpi, expt, bits, i, rd, &irv))
549 1.1 kleink goto ret;
550 1.1 kleink e1 -= e;
551 1.1 kleink goto rv_notOK;
552 1.1 kleink #endif
553 1.1 kleink }
554 1.1 kleink i = DBL_DIG - nd;
555 1.1 kleink if (e <= Ten_pmax + i) {
556 1.1 kleink /* A fancier test would sometimes let us do
557 1.1 kleink * this for larger i values.
558 1.1 kleink */
559 1.1 kleink e2 = e - i;
560 1.1 kleink e1 -= i;
561 1.1 kleink dval(rv) *= tens[i];
562 1.1 kleink #ifdef VAX
563 1.1 kleink /* VAX exponent range is so narrow we must
564 1.1 kleink * worry about overflow here...
565 1.1 kleink */
566 1.1 kleink vax_ovfl_check:
567 1.1 kleink dval(adj) = dval(rv);
568 1.1 kleink word0(adj) -= P*Exp_msk1;
569 1.1 kleink /* adj = */ rounded_product(dval(adj), tens[e2]);
570 1.1 kleink if ((word0(adj) & Exp_mask)
571 1.1 kleink > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
572 1.1 kleink goto rv_notOK;
573 1.1 kleink word0(adj) += P*Exp_msk1;
574 1.1 kleink dval(rv) = dval(adj);
575 1.1 kleink #else
576 1.1 kleink /* rv = */ rounded_product(dval(rv), tens[e2]);
577 1.1 kleink #endif
578 1.2 kleink if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
579 1.1 kleink goto ret;
580 1.1 kleink e1 -= e2;
581 1.1 kleink }
582 1.1 kleink }
583 1.1 kleink #ifndef Inaccurate_Divide
584 1.1 kleink else if (e >= -Ten_pmax) {
585 1.1 kleink /* rv = */ rounded_quotient(dval(rv), tens[-e]);
586 1.2 kleink if (rvOK(dval(rv), fpi, expt, bits, 0, rd, &irv))
587 1.1 kleink goto ret;
588 1.1 kleink e1 -= e;
589 1.1 kleink }
590 1.1 kleink #endif
591 1.1 kleink }
592 1.1 kleink rv_notOK:
593 1.1 kleink e1 += nd - k;
594 1.1 kleink
595 1.1 kleink /* Get starting approximation = rv * 10**e1 */
596 1.1 kleink
597 1.1 kleink e2 = 0;
598 1.1 kleink if (e1 > 0) {
599 1.1 kleink if ( (i = e1 & 15) !=0)
600 1.1 kleink dval(rv) *= tens[i];
601 1.1 kleink if (e1 &= ~15) {
602 1.2 kleink e1 = (unsigned int)e1 >> 4;
603 1.2 kleink while(e1 >= (1 << (n_bigtens-1))) {
604 1.1 kleink e2 += ((word0(rv) & Exp_mask)
605 1.1 kleink >> Exp_shift1) - Bias;
606 1.1 kleink word0(rv) &= ~Exp_mask;
607 1.1 kleink word0(rv) |= Bias << Exp_shift1;
608 1.1 kleink dval(rv) *= bigtens[n_bigtens-1];
609 1.2 kleink e1 -= 1 << (n_bigtens-1);
610 1.1 kleink }
611 1.1 kleink e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
612 1.1 kleink word0(rv) &= ~Exp_mask;
613 1.1 kleink word0(rv) |= Bias << Exp_shift1;
614 1.2 kleink for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
615 1.1 kleink if (e1 & 1)
616 1.1 kleink dval(rv) *= bigtens[j];
617 1.1 kleink }
618 1.1 kleink }
619 1.1 kleink else if (e1 < 0) {
620 1.1 kleink e1 = -e1;
621 1.1 kleink if ( (i = e1 & 15) !=0)
622 1.1 kleink dval(rv) /= tens[i];
623 1.1 kleink if (e1 &= ~15) {
624 1.2 kleink e1 = (unsigned int)e1 >> 4;
625 1.2 kleink while(e1 >= (1 << (n_bigtens-1))) {
626 1.1 kleink e2 += ((word0(rv) & Exp_mask)
627 1.1 kleink >> Exp_shift1) - Bias;
628 1.1 kleink word0(rv) &= ~Exp_mask;
629 1.1 kleink word0(rv) |= Bias << Exp_shift1;
630 1.1 kleink dval(rv) *= tinytens[n_bigtens-1];
631 1.2 kleink e1 -= 1 << (n_bigtens-1);
632 1.1 kleink }
633 1.1 kleink e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
634 1.1 kleink word0(rv) &= ~Exp_mask;
635 1.1 kleink word0(rv) |= Bias << Exp_shift1;
636 1.2 kleink for(j = 0; e1 > 0; j++, e1 = (unsigned int)e1 >> 1)
637 1.1 kleink if (e1 & 1)
638 1.1 kleink dval(rv) *= tinytens[j];
639 1.1 kleink }
640 1.1 kleink }
641 1.1 kleink #ifdef IBM
642 1.1 kleink /* e2 is a correction to the (base 2) exponent of the return
643 1.1 kleink * value, reflecting adjustments above to avoid overflow in the
644 1.1 kleink * native arithmetic. For native IBM (base 16) arithmetic, we
645 1.1 kleink * must multiply e2 by 4 to change from base 16 to 2.
646 1.1 kleink */
647 1.1 kleink e2 <<= 2;
648 1.1 kleink #endif
649 1.1 kleink rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */
650 1.1 kleink rve += e2;
651 1.1 kleink if ((j = rvbits - nbits) > 0) {
652 1.1 kleink rshift(rvb, j);
653 1.1 kleink rvbits = nbits;
654 1.1 kleink rve += j;
655 1.1 kleink }
656 1.1 kleink bb0 = 0; /* trailing zero bits in rvb */
657 1.1 kleink e2 = rve + rvbits - nbits;
658 1.1 kleink if (e2 > fpi->emax + 1)
659 1.1 kleink goto huge;
660 1.1 kleink rve1 = rve + rvbits - nbits;
661 1.1 kleink if (e2 < (emin = fpi->emin)) {
662 1.1 kleink denorm = 1;
663 1.1 kleink j = rve - emin;
664 1.1 kleink if (j > 0) {
665 1.1 kleink rvb = lshift(rvb, j);
666 1.1 kleink rvbits += j;
667 1.1 kleink }
668 1.1 kleink else if (j < 0) {
669 1.1 kleink rvbits += j;
670 1.1 kleink if (rvbits <= 0) {
671 1.1 kleink if (rvbits < -1) {
672 1.1 kleink ufl:
673 1.1 kleink rvb->wds = 0;
674 1.1 kleink rvb->x[0] = 0;
675 1.2 kleink *expt = emin;
676 1.1 kleink irv = STRTOG_Underflow | STRTOG_Inexlo;
677 1.1 kleink goto ret;
678 1.1 kleink }
679 1.1 kleink rvb->x[0] = rvb->wds = rvbits = 1;
680 1.1 kleink }
681 1.1 kleink else
682 1.1 kleink rshift(rvb, -j);
683 1.1 kleink }
684 1.1 kleink rve = rve1 = emin;
685 1.1 kleink if (sudden_underflow && e2 + 1 < emin)
686 1.1 kleink goto ufl;
687 1.1 kleink }
688 1.1 kleink
689 1.1 kleink /* Now the hard part -- adjusting rv to the correct value.*/
690 1.1 kleink
691 1.1 kleink /* Put digits into bd: true value = bd * 10^e */
692 1.1 kleink
693 1.1 kleink bd0 = s2b(s0, nd0, nd, y);
694 1.1 kleink
695 1.1 kleink for(;;) {
696 1.1 kleink bd = Balloc(bd0->k);
697 1.1 kleink Bcopy(bd, bd0);
698 1.1 kleink bb = Balloc(rvb->k);
699 1.1 kleink Bcopy(bb, rvb);
700 1.1 kleink bbbits = rvbits - bb0;
701 1.1 kleink bbe = rve + bb0;
702 1.1 kleink bs = i2b(1);
703 1.1 kleink
704 1.1 kleink if (e >= 0) {
705 1.1 kleink bb2 = bb5 = 0;
706 1.1 kleink bd2 = bd5 = e;
707 1.1 kleink }
708 1.1 kleink else {
709 1.1 kleink bb2 = bb5 = -e;
710 1.1 kleink bd2 = bd5 = 0;
711 1.1 kleink }
712 1.1 kleink if (bbe >= 0)
713 1.1 kleink bb2 += bbe;
714 1.1 kleink else
715 1.1 kleink bd2 -= bbe;
716 1.1 kleink bs2 = bb2;
717 1.1 kleink j = nbits + 1 - bbbits;
718 1.1 kleink i = bbe + bbbits - nbits;
719 1.1 kleink if (i < emin) /* denormal */
720 1.1 kleink j += i - emin;
721 1.1 kleink bb2 += j;
722 1.1 kleink bd2 += j;
723 1.1 kleink i = bb2 < bd2 ? bb2 : bd2;
724 1.1 kleink if (i > bs2)
725 1.1 kleink i = bs2;
726 1.1 kleink if (i > 0) {
727 1.1 kleink bb2 -= i;
728 1.1 kleink bd2 -= i;
729 1.1 kleink bs2 -= i;
730 1.1 kleink }
731 1.1 kleink if (bb5 > 0) {
732 1.1 kleink bs = pow5mult(bs, bb5);
733 1.1 kleink bb1 = mult(bs, bb);
734 1.1 kleink Bfree(bb);
735 1.1 kleink bb = bb1;
736 1.1 kleink }
737 1.1 kleink bb2 -= bb0;
738 1.1 kleink if (bb2 > 0)
739 1.1 kleink bb = lshift(bb, bb2);
740 1.1 kleink else if (bb2 < 0)
741 1.1 kleink rshift(bb, -bb2);
742 1.1 kleink if (bd5 > 0)
743 1.1 kleink bd = pow5mult(bd, bd5);
744 1.1 kleink if (bd2 > 0)
745 1.1 kleink bd = lshift(bd, bd2);
746 1.1 kleink if (bs2 > 0)
747 1.1 kleink bs = lshift(bs, bs2);
748 1.1 kleink asub = 1;
749 1.1 kleink inex = STRTOG_Inexhi;
750 1.1 kleink delta = diff(bb, bd);
751 1.1 kleink if (delta->wds <= 1 && !delta->x[0])
752 1.1 kleink break;
753 1.1 kleink dsign = delta->sign;
754 1.1 kleink delta->sign = finished = 0;
755 1.1 kleink L = 0;
756 1.1 kleink i = cmp(delta, bs);
757 1.1 kleink if (rd && i <= 0) {
758 1.1 kleink irv = STRTOG_Normal;
759 1.1 kleink if ( (finished = dsign ^ (rd&1)) !=0) {
760 1.1 kleink if (dsign != 0) {
761 1.1 kleink irv |= STRTOG_Inexhi;
762 1.1 kleink goto adj1;
763 1.1 kleink }
764 1.1 kleink irv |= STRTOG_Inexlo;
765 1.1 kleink if (rve1 == emin)
766 1.1 kleink goto adj1;
767 1.1 kleink for(i = 0, j = nbits; j >= ULbits;
768 1.1 kleink i++, j -= ULbits) {
769 1.1 kleink if (rvb->x[i] & ALL_ON)
770 1.1 kleink goto adj1;
771 1.1 kleink }
772 1.1 kleink if (j > 1 && lo0bits(rvb->x + i) < j - 1)
773 1.1 kleink goto adj1;
774 1.1 kleink rve = rve1 - 1;
775 1.1 kleink rvb = set_ones(rvb, rvbits = nbits);
776 1.1 kleink break;
777 1.1 kleink }
778 1.1 kleink irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi;
779 1.1 kleink break;
780 1.1 kleink }
781 1.1 kleink if (i < 0) {
782 1.1 kleink /* Error is less than half an ulp -- check for
783 1.1 kleink * special case of mantissa a power of two.
784 1.1 kleink */
785 1.1 kleink irv = dsign
786 1.1 kleink ? STRTOG_Normal | STRTOG_Inexlo
787 1.1 kleink : STRTOG_Normal | STRTOG_Inexhi;
788 1.1 kleink if (dsign || bbbits > 1 || denorm || rve1 == emin)
789 1.1 kleink break;
790 1.1 kleink delta = lshift(delta,1);
791 1.1 kleink if (cmp(delta, bs) > 0) {
792 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexlo;
793 1.1 kleink goto drop_down;
794 1.1 kleink }
795 1.1 kleink break;
796 1.1 kleink }
797 1.1 kleink if (i == 0) {
798 1.1 kleink /* exactly half-way between */
799 1.1 kleink if (dsign) {
800 1.1 kleink if (denorm && all_on(rvb, rvbits)) {
801 1.1 kleink /*boundary case -- increment exponent*/
802 1.1 kleink rvb->wds = 1;
803 1.1 kleink rvb->x[0] = 1;
804 1.1 kleink rve = emin + nbits - (rvbits = 1);
805 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexhi;
806 1.1 kleink denorm = 0;
807 1.1 kleink break;
808 1.1 kleink }
809 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexlo;
810 1.1 kleink }
811 1.1 kleink else if (bbbits == 1) {
812 1.1 kleink irv = STRTOG_Normal;
813 1.1 kleink drop_down:
814 1.1 kleink /* boundary case -- decrement exponent */
815 1.1 kleink if (rve1 == emin) {
816 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexhi;
817 1.1 kleink if (rvb->wds == 1 && rvb->x[0] == 1)
818 1.1 kleink sudden_underflow = 1;
819 1.1 kleink break;
820 1.1 kleink }
821 1.1 kleink rve -= nbits;
822 1.1 kleink rvb = set_ones(rvb, rvbits = nbits);
823 1.1 kleink break;
824 1.1 kleink }
825 1.1 kleink else
826 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexhi;
827 1.2 kleink if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
828 1.1 kleink break;
829 1.1 kleink if (dsign) {
830 1.1 kleink rvb = increment(rvb);
831 1.1 kleink if ( (j = rvbits & kmask) !=0)
832 1.1 kleink j = ULbits - j;
833 1.2 kleink if (hi0bits(rvb->x[(unsigned int)(rvb->wds - 1)
834 1.2 kleink >> kshift])
835 1.1 kleink != j)
836 1.1 kleink rvbits++;
837 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexhi;
838 1.1 kleink }
839 1.1 kleink else {
840 1.1 kleink if (bbbits == 1)
841 1.1 kleink goto undfl;
842 1.1 kleink decrement(rvb);
843 1.1 kleink irv = STRTOG_Normal | STRTOG_Inexlo;
844 1.1 kleink }
845 1.1 kleink break;
846 1.1 kleink }
847 1.1 kleink if ((dval(adj) = ratio(delta, bs)) <= 2.) {
848 1.1 kleink adj1:
849 1.1 kleink inex = STRTOG_Inexlo;
850 1.1 kleink if (dsign) {
851 1.1 kleink asub = 0;
852 1.1 kleink inex = STRTOG_Inexhi;
853 1.1 kleink }
854 1.1 kleink else if (denorm && bbbits <= 1) {
855 1.1 kleink undfl:
856 1.1 kleink rvb->wds = 0;
857 1.1 kleink rve = emin;
858 1.1 kleink irv = STRTOG_Underflow | STRTOG_Inexlo;
859 1.1 kleink break;
860 1.1 kleink }
861 1.1 kleink adj0 = dval(adj) = 1.;
862 1.1 kleink }
863 1.1 kleink else {
864 1.1 kleink adj0 = dval(adj) *= 0.5;
865 1.1 kleink if (dsign) {
866 1.1 kleink asub = 0;
867 1.1 kleink inex = STRTOG_Inexlo;
868 1.1 kleink }
869 1.1 kleink if (dval(adj) < 2147483647.) {
870 1.1 kleink L = adj0;
871 1.1 kleink adj0 -= L;
872 1.1 kleink switch(rd) {
873 1.1 kleink case 0:
874 1.1 kleink if (adj0 >= .5)
875 1.1 kleink goto inc_L;
876 1.1 kleink break;
877 1.1 kleink case 1:
878 1.1 kleink if (asub && adj0 > 0.)
879 1.1 kleink goto inc_L;
880 1.1 kleink break;
881 1.1 kleink case 2:
882 1.1 kleink if (!asub && adj0 > 0.) {
883 1.1 kleink inc_L:
884 1.1 kleink L++;
885 1.1 kleink inex = STRTOG_Inexact - inex;
886 1.1 kleink }
887 1.1 kleink }
888 1.1 kleink dval(adj) = L;
889 1.1 kleink }
890 1.1 kleink }
891 1.1 kleink y = rve + rvbits;
892 1.1 kleink
893 1.1 kleink /* adj *= ulp(dval(rv)); */
894 1.1 kleink /* if (asub) rv -= adj; else rv += adj; */
895 1.1 kleink
896 1.1 kleink if (!denorm && rvbits < nbits) {
897 1.1 kleink rvb = lshift(rvb, j = nbits - rvbits);
898 1.1 kleink rve -= j;
899 1.1 kleink rvbits = nbits;
900 1.1 kleink }
901 1.1 kleink ab = d2b(dval(adj), &abe, &abits);
902 1.1 kleink if (abe < 0)
903 1.1 kleink rshift(ab, -abe);
904 1.1 kleink else if (abe > 0)
905 1.1 kleink ab = lshift(ab, abe);
906 1.1 kleink rvb0 = rvb;
907 1.1 kleink if (asub) {
908 1.1 kleink /* rv -= adj; */
909 1.1 kleink j = hi0bits(rvb->x[rvb->wds-1]);
910 1.1 kleink rvb = diff(rvb, ab);
911 1.1 kleink k = rvb0->wds - 1;
912 1.1 kleink if (denorm)
913 1.1 kleink /* do nothing */;
914 1.1 kleink else if (rvb->wds <= k
915 1.1 kleink || hi0bits( rvb->x[k]) >
916 1.1 kleink hi0bits(rvb0->x[k])) {
917 1.1 kleink /* unlikely; can only have lost 1 high bit */
918 1.1 kleink if (rve1 == emin) {
919 1.1 kleink --rvbits;
920 1.1 kleink denorm = 1;
921 1.1 kleink }
922 1.1 kleink else {
923 1.1 kleink rvb = lshift(rvb, 1);
924 1.1 kleink --rve;
925 1.1 kleink --rve1;
926 1.1 kleink L = finished = 0;
927 1.1 kleink }
928 1.1 kleink }
929 1.1 kleink }
930 1.1 kleink else {
931 1.1 kleink rvb = sum(rvb, ab);
932 1.1 kleink k = rvb->wds - 1;
933 1.1 kleink if (k >= rvb0->wds
934 1.1 kleink || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) {
935 1.1 kleink if (denorm) {
936 1.1 kleink if (++rvbits == nbits)
937 1.1 kleink denorm = 0;
938 1.1 kleink }
939 1.1 kleink else {
940 1.1 kleink rshift(rvb, 1);
941 1.1 kleink rve++;
942 1.1 kleink rve1++;
943 1.1 kleink L = 0;
944 1.1 kleink }
945 1.1 kleink }
946 1.1 kleink }
947 1.1 kleink Bfree(ab);
948 1.1 kleink Bfree(rvb0);
949 1.1 kleink if (finished)
950 1.1 kleink break;
951 1.1 kleink
952 1.1 kleink z = rve + rvbits;
953 1.1 kleink if (y == z && L) {
954 1.1 kleink /* Can we stop now? */
955 1.1 kleink tol = dval(adj) * 5e-16; /* > max rel error */
956 1.1 kleink dval(adj) = adj0 - .5;
957 1.1 kleink if (dval(adj) < -tol) {
958 1.1 kleink if (adj0 > tol) {
959 1.1 kleink irv |= inex;
960 1.1 kleink break;
961 1.1 kleink }
962 1.1 kleink }
963 1.1 kleink else if (dval(adj) > tol && adj0 < 1. - tol) {
964 1.1 kleink irv |= inex;
965 1.1 kleink break;
966 1.1 kleink }
967 1.1 kleink }
968 1.1 kleink bb0 = denorm ? 0 : trailz(rvb);
969 1.1 kleink Bfree(bb);
970 1.1 kleink Bfree(bd);
971 1.1 kleink Bfree(bs);
972 1.1 kleink Bfree(delta);
973 1.1 kleink }
974 1.1 kleink if (!denorm && (j = nbits - rvbits)) {
975 1.1 kleink if (j > 0)
976 1.1 kleink rvb = lshift(rvb, j);
977 1.1 kleink else
978 1.1 kleink rshift(rvb, -j);
979 1.1 kleink rve -= j;
980 1.1 kleink }
981 1.2 kleink *expt = rve;
982 1.1 kleink Bfree(bb);
983 1.1 kleink Bfree(bd);
984 1.1 kleink Bfree(bs);
985 1.1 kleink Bfree(bd0);
986 1.1 kleink Bfree(delta);
987 1.1 kleink if (rve > fpi->emax) {
988 1.1 kleink huge:
989 1.1 kleink rvb->wds = 0;
990 1.1 kleink irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
991 1.1 kleink #ifndef NO_ERRNO
992 1.1 kleink errno = ERANGE;
993 1.1 kleink #endif
994 1.2 kleink #ifdef INFNAN_CHECK
995 1.1 kleink infnanexp:
996 1.2 kleink #endif
997 1.2 kleink *expt = fpi->emax + 1;
998 1.1 kleink }
999 1.1 kleink ret:
1000 1.1 kleink if (denorm) {
1001 1.1 kleink if (sudden_underflow) {
1002 1.1 kleink rvb->wds = 0;
1003 1.1 kleink irv = STRTOG_Underflow | STRTOG_Inexlo;
1004 1.1 kleink }
1005 1.1 kleink else {
1006 1.1 kleink irv = (irv & ~STRTOG_Retmask) |
1007 1.1 kleink (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero);
1008 1.1 kleink if (irv & STRTOG_Inexact)
1009 1.1 kleink irv |= STRTOG_Underflow;
1010 1.1 kleink }
1011 1.1 kleink }
1012 1.1 kleink if (se)
1013 1.2 kleink *se = __UNCONST(s);
1014 1.1 kleink if (sign)
1015 1.1 kleink irv |= STRTOG_Neg;
1016 1.1 kleink if (rvb) {
1017 1.1 kleink copybits(bits, nbits, rvb);
1018 1.1 kleink Bfree(rvb);
1019 1.1 kleink }
1020 1.1 kleink return irv;
1021 1.1 kleink }
1022