8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / gen / common / decimal_bin.c
blobc398f592b74fba35aac169f2749ab17229fde654
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1988-1995, by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 /* Conversion between binary and decimal floating point. */
31 #include "base_conversion.h"
33 void
34 decimal_to_binary_integer(ds, ndigs, nzeros, nsig, pb)
35 char ds[]; /* Input decimal integer string. */
36 unsigned ndigs; /* Input number of explicit digits in ds. */
37 unsigned nzeros; /* Input number of implicit trailing zeros. */
38 unsigned nsig; /* Input number of significant bits required. */
39 _big_float *pb; /* Pointer to big_float to receive result. */
42 * Converts a decimal integer string ds with ndigs explicit leading digits
43 * and nzeros implicit trailing zeros to a _big_float **pb, which only
44 * requires nsig significand bits.
46 /* Inexactness is indicated by pb->bsignificand[0] |= 1. */
48 * If the input is too big for a big_float, pb->bexponent is set to 0x7fff.
52 unsigned nzout;
53 _big_float d, *pbout;
55 d.bsize = _BIG_FLOAT_SIZE;
56 _integerstring_to_big_decimal(ds, ndigs, nzeros, &nzout, &d);
57 _big_decimal_to_big_binary(&d, pb);
58 if (nzout != 0) {
59 _big_float_times_power(pb, 10, (int) nzout, (int) nsig, &pbout);
60 switch ((unsigned int)pbout) {
61 case ((unsigned int)BIG_FLOAT_TIMES_TOOBIG):
62 #ifdef DEBUG
63 (void) printf(" decimal_to_binary_integer: decimal exponent %d too large for tables ", nzout);
64 #endif
65 pb->bexponent = 0x7fff;
66 break;
67 case ((unsigned int)BIG_FLOAT_TIMES_NOMEM):
69 char bcastring[80];
71 (void) sprintf(bcastring, " decimal exponent %d ", nzout);
72 _base_conversion_abort(ENOMEM, bcastring);
73 break;
75 default:
76 #ifdef DEBUG
77 if (pbout != pb)
78 (void) printf(" decimal_to_binary_integer: large decimal exponent %d needs heap buffer \n", nzout);
79 printf(" decimal_to_binary_integer: product ");
80 _display_big_float(pb, 2);
81 #endif
82 if (pbout != pb) { /* We don't really need such
83 * a large product; the
84 * target can't be more than
85 * a quad! */
86 int i, allweneed;
88 allweneed = 2 + (nsig + 2) / 16;
89 for (i = 0; i < allweneed; i++)
90 pb->bsignificand[i] = pbout->bsignificand[i + pbout->blength - allweneed];
91 for (i = 0; (pbout->bsignificand[i] == 0); i++);
92 if (i < (pbout->blength - allweneed))
93 pb->bsignificand[0] |= 1; /* Stick discarded bits. */
95 pb->blength = allweneed;
96 pb->bexponent = pbout->bexponent + 16 * (pbout->blength - allweneed);
97 #ifdef DEBUG
98 printf(" decimal_to_binary_integer: removed %d excess digits from product \n", pbout->blength - allweneed);
99 _display_big_float(pb, 2);
100 #endif
101 _free_big_float(pbout);
103 break;
108 void
109 decimal_to_binary_fraction(ds, ndigs, nzeros, nsig, pb)
110 char ds[]; /* Decimal integer string input. */
111 unsigned ndigs; /* Number of explicit digits to read. */
112 unsigned nzeros; /* Number of implicit leading zeros before
113 * digits. */
114 unsigned nsig; /* Number of significant bits needed. */
115 _big_float *pb; /* Pointer to intended big_float result. */
118 * Converts an explicit decimal string *ds[0]..*ds[ndigs-1] preceded by
119 * nzeros implicit leading zeros after the point into a big_float at *pb. If
120 * the input does not fit exactly in a big_float, the least significant bit
121 * of pbout->significand is stuck on. If the input is too big for the base
122 * conversion tables, pb->bexponent is set to 0x7fff.
126 unsigned twopower, twosig;
127 int i, excess;
128 _big_float d, *pdout;
130 d.bsize = _BIG_FLOAT_SIZE;
131 _fractionstring_to_big_decimal(ds, ndigs, nzeros, &d);
133 twopower = nsig + 3 + (((nzeros + 1) * (unsigned long) 217706) >> 16);
134 twosig = 1 + (((nsig + 2) * (unsigned long) 19729) >> 16);
136 #ifdef DEBUG
137 printf(" decimal_to_binary_fraction sigbits %d twopower %d twosig %d \n",
138 nsig, twopower, twosig);
139 #endif
140 _big_float_times_power(&d, 2, (int) twopower, (int) twosig, &pdout);
141 switch ((unsigned int)pdout) {
142 case ((unsigned int)BIG_FLOAT_TIMES_TOOBIG):
143 #ifdef DEBUG
144 (void) printf(" decimal_to_binary_fraction binary exponent %d too large for tables ", twopower);
145 #endif
146 pb->bexponent = 0x7fff;
147 goto ret;
148 case ((unsigned int)BIG_FLOAT_TIMES_NOMEM):
150 char bcastring[80];
152 (void) sprintf(bcastring, " binary exponent %d ", twopower);
153 _base_conversion_abort(ENOMEM, bcastring);
154 break;
156 default:
157 #ifdef DEBUG
158 if (&d != pdout)
159 printf(" decimal_to_binary_fraction large binary exponent %d needs heap buffer \n", twopower);
160 printf(" product ");
161 _display_big_float(pdout, 10);
162 #endif
163 break;
167 if (pdout->bexponent <= -4) {
168 /* Have computed appropriate decimal part; now toss fraction. */
169 excess = (-pdout->bexponent) / 4;
170 #ifdef DEBUG
171 printf(" discard %d excess fraction digits \n", 4 * excess);
172 #endif
173 for (i = 0; (i < excess) && ((pdout)->bsignificand[i] == 0); i++);
174 if (i < excess)
175 (pdout)->bsignificand[excess] |= 1; /* Sticky bit for
176 * discarded fraction. */
177 for (i = excess; i < (pdout)->blength; i++)
178 (pdout)->bsignificand[i - excess] = (pdout)->bsignificand[i];
180 (pdout)->blength -= excess;
181 (pdout)->bexponent += 4 * excess;
183 _big_decimal_to_big_binary(pdout, pb);
184 if (pdout != &d)
185 _free_big_float(pdout);
186 pb->bexponent = -twopower;
188 ret:
189 return;
192 void
193 decimal_to_unpacked(px, pd, significant_bits)
194 unpacked *px;
195 decimal_record *pd;
196 unsigned significant_bits;
199 * Converts *pd to *px so that *px can be correctly rounded. significant_bits
200 * tells how many bits will be significant in the final result to avoid
201 * superfluous computation. Inexactness is communicated by sticking on the
202 * lsb of px->significand[UNPACKED_SIZE-1]. Integer buffer overflow is
203 * indicated with a huge positive exponent.
207 int frac_bits, sigint;
208 unsigned length, ndigs, ntz, nlz, ifrac, nfrac;
209 _big_float bi, bf, *ptounpacked = &bi;
211 px->sign = pd->sign;
212 px->fpclass = pd->fpclass;
213 if ((px->fpclass != fp_normal) && (px->fpclass != fp_subnormal))
214 goto ret;
215 for (length = 0; pd->ds[length] != 0; length++);
216 if (length == 0) { /* A zero significand slipped by. */
217 px->fpclass = fp_zero;
218 goto ret;
220 /* Length contains the number of explicit digits in string. */
221 if (pd->exponent >= 0) {/* All integer digits. */
222 ndigs = length;
223 ntz = pd->exponent; /* Trailing zeros. */
224 ifrac = 0;
225 nfrac = 0; /* No fraction digits. */
226 nlz = 0;
227 } else if (length <= -pd->exponent) { /* No integer digits. */
228 ndigs = 0;
229 ntz = 0;
230 ifrac = 0;
231 nfrac = length;
232 nlz = -pd->exponent - length; /* Leading zeros. */
233 } else { /* Some integer digits, some fraction digits. */
234 ndigs = length + pd->exponent;
235 ntz = 0;
236 ifrac = ndigs;
237 nfrac = -pd->exponent;
238 nlz = 0;
239 while ((pd->ds[ifrac] == '0') && (nfrac != 0)) {
240 ifrac++;
241 nfrac--;
242 nlz++;
243 } /* Remove leading zeros. */
245 if (ndigs != 0) { /* Convert integer digits. */
247 bi.bsize = _BIG_FLOAT_SIZE;
248 decimal_to_binary_integer(pd->ds, ndigs, ntz, significant_bits, &bi);
249 if (bi.bexponent == 0x7fff) { /* Too big for buffer. */
250 px->exponent = 0x000fffff;
251 px->significand[0] = 0x80000000;
252 goto ret;
254 sigint = 16 * (bi.blength + bi.bexponent - 1);
255 if (sigint < 0)
256 sigint = 0;
257 } else { /* No integer digits. */
258 bi.blength = 0;
259 bi.bsignificand[0] = 0;
260 bi.bexponent = 0;
261 sigint = 0;
263 frac_bits = significant_bits - sigint + 2;
264 bf.blength = 0;
265 if ((nfrac != 0) && (frac_bits > 0)) { /* Convert fraction digits,
266 * even if we only need a
267 * round or sticky. */
269 bf.bsize = _BIG_FLOAT_SIZE;
270 decimal_to_binary_fraction(&(pd->ds[ifrac]), nfrac, nlz, (unsigned) frac_bits, &bf);
271 } else { /* Only need fraction bits for sticky. */
272 if (nfrac != 0)
273 bi.bsignificand[0] |= 1; /* Stick for fraction. */
275 if (bi.blength == 0) { /* No integer digits; all fraction. */
276 if (bf.bexponent == 0x7fff) { /* Buffer overflowed. */
277 px->exponent = -0x000fffff;
278 px->significand[0] = 0x80000000;
279 goto ret;
281 ptounpacked = &bf; /* Exceptional case - all fraction. */
282 goto punpack;
284 if (bf.blength != 0) { /* Combine integer and fraction bits. */
285 int expdiff = bi.bexponent - (bf.bexponent + 16 * (bf.blength - 1)); /* Exponent difference. */
286 int uneeded = 2 + (significant_bits + 2) / 16; /* Number of big float
287 * digits needed. */
288 int nmove, leftshift, i, if0;
290 #ifdef DEBUG
291 printf(" bi+bf exponent diff is %d \n", expdiff);
292 printf(" need %d big float digits \n", uneeded);
293 assert(bi.blength != 0);
294 assert(bf.blength != 0);
295 assert(bi.bsignificand[bi.blength - 1] != 0); /* Normalized bi. */
296 assert(bf.bsignificand[bf.blength - 1] != 0); /* Normalized bf. */
297 assert(bi.bexponent >= 0); /* bi is all integer */
298 assert(((-bf.bexponent - 16 * (bf.blength - 1)) >= 16) ||
299 ((bf.bsignificand[bf.blength - 1] >> (-bf.bexponent - 16 * (bf.blength - 1))) == 0));
300 /* assert either bf << 1 or bf < 1 */
302 * Assert that integer and fraction parts don't overlap by
303 * more than one big digit.
305 assert(expdiff > 0);
306 assert(uneeded <= (2 * UNPACKED_SIZE));
307 #endif
310 if (bi.blength >= uneeded) { /* bi will overflow unpacked,
311 * so bf is just a sticky. */
312 bi.bsignificand[0] |= 1;
313 goto punpack;
315 leftshift = 16 - (expdiff % 16);
316 if (leftshift > 0) { /* shift bf to align with bi. */
317 expdiff += 16 * bf.blength;
318 _left_shift_base_two(&bf, (short unsigned) leftshift);
319 expdiff -= 16 * bf.blength; /* If bf.blength is
320 * longer, adjust
321 * expdiff. */
323 expdiff += leftshift;
324 expdiff /= 16; /* Remaining expdiff in _BIG_FLOAT_DIGITS. */
325 expdiff--;
326 #ifdef DEBUG
327 assert(expdiff >= 0); /* expdiff is now equal to the size
328 * of the hole between bi and bf. */
329 #endif
330 nmove = uneeded - bi.blength;
331 /* nmove is the number of words to add to bi. */
332 if (nmove < 0)
333 nmove = 0;
334 if (nmove > (expdiff + bf.blength))
335 nmove = (expdiff + bf.blength);
336 #ifdef DEBUG
337 printf(" increase bi by %d words to merge \n", nmove);
338 #endif
339 if (nmove == 0)
340 i = -1;
341 else
342 for (i = (bi.blength - 1 + nmove); i >= nmove; i--)
343 bi.bsignificand[i] = bi.bsignificand[i - nmove];
344 for (; (i >= 0) && (expdiff > 0); i--) { /* Fill hole with zeros. */
345 expdiff--;
346 bi.bsignificand[i] = 0;
348 if0 = i;
349 for (; i >= 0; i--)
350 bi.bsignificand[i] = bf.bsignificand[i + bf.blength - 1 - if0];
351 for (i = (bf.blength - 2 - if0); bf.bsignificand[i] == 0; i--);
352 /* Find first non-zero. */
353 if (i >= 0)
354 bi.bsignificand[0] |= 1; /* If non-zero found,
355 * stick it. */
356 bi.blength += nmove;
357 bi.bexponent -= 16 * nmove;
358 goto punpack;
360 punpack:
361 ptounpacked->bsignificand[0] |= pd->more; /* Stick in any lost
362 * digits. */
364 #ifdef DEBUG
365 printf(" merged bi and bf: ");
366 _display_big_float(ptounpacked, 2);
367 #endif
369 _big_binary_to_unpacked(ptounpacked, px);
371 ret:
372 return;
375 /* PUBLIC FUNCTIONS */
378 * decimal_to_floating routines convert the decimal record at *pd to the
379 * floating type item at *px, observing the modes specified in *pm and
380 * setting exceptions in *ps.
382 * pd->sign and pd->fpclass are always taken into account.
384 * pd->exponent, pd->ds and pd->ndigits are used when pd->fpclass is
385 * fp_normal or fp_subnormal. In these cases pd->ds is expected to
386 * contain one or more ascii digits followed by a null and pd->ndigits
387 * is assumed to be the length of the string pd->ds. Notice that for
388 * efficiency reasons, the assumption that pd->ndigits == strlen(pd->ds)
389 * is NEVER verified.
391 * px is set to a correctly rounded approximation to
392 * (sign)*(ds)*10**(exponent) If pd->more != 0 then additional nonzero digits
393 * are assumed to follow those in ds; fp_inexact is set accordingly.
395 * Thus if pd->exponent == -2 and pd->ds = "1234", *px will get 12.34 rounded to
396 * storage precision.
398 * px is correctly rounded according to the IEEE rounding modes in pm->rd. *ps
399 * is set to contain fp_inexact, fp_underflow, or fp_overflow if any of these
400 * arise.
402 * pm->df and pm->ndigits are never used.
406 void
407 decimal_to_single(px, pm, pd, ps)
408 single *px;
409 decimal_mode *pm;
410 decimal_record *pd;
411 fp_exception_field_type *ps;
413 single_equivalence kluge;
414 unpacked u;
416 *ps = 0; /* Initialize to no floating-point
417 * exceptions. */
418 kluge.f.msw.sign = pd->sign ? 1 : 0;
419 switch (pd->fpclass) {
420 case fp_zero:
421 kluge.f.msw.exponent = 0;
422 kluge.f.msw.significand = 0;
423 break;
424 case fp_infinity:
425 kluge.f.msw.exponent = 0xff;
426 kluge.f.msw.significand = 0;
427 break;
428 case fp_quiet:
429 kluge.f.msw.exponent = 0xff;
430 kluge.f.msw.significand = 0x7fffff;
431 break;
432 case fp_signaling:
433 kluge.f.msw.exponent = 0xff;
434 kluge.f.msw.significand = 0x3fffff;
435 break;
436 default:
437 if (pd->exponent > SINGLE_MAXE) { /* Guaranteed overflow. */
438 u.sign = pd->sign == 0 ? 0 : 1;
439 u.fpclass = fp_normal;
440 u.exponent = 0x000fffff;
441 u.significand[0] = 0x80000000;
442 } else if (pd->exponent >= -SINGLE_MAXE) { /* Guaranteed in range. */
443 goto inrange;
444 } else if (pd->exponent <= (-SINGLE_MAXE - DECIMAL_STRING_LENGTH)) { /* Guaranteed deep
445 * underflow. */
446 goto underflow;
447 } else { /* Deep underflow possible, depending on
448 * string length. */
449 int i;
451 for (i = 0; (pd->ds[i] != 0) && (i < (-pd->exponent - SINGLE_MAXE)); i++);
452 if (i < (-pd->exponent - SINGLE_MAXE)) { /* Deep underflow */
453 underflow:
454 u.sign = pd->sign == 0 ? 0 : 1;
455 u.fpclass = fp_normal;
456 u.exponent = -0x000fffff;
457 u.significand[0] = 0x80000000;
458 } else {/* In range. */
459 inrange:
460 decimal_to_unpacked(&u, pd, 24);
463 _fp_current_exceptions = 0;
464 _fp_current_direction = pm->rd;
465 _pack_single(&u, &kluge.x);
466 *ps = _fp_current_exceptions;
468 *px = kluge.x;
471 void
472 decimal_to_double(px, pm, pd, ps)
473 double *px;
474 decimal_mode *pm;
475 decimal_record *pd;
476 fp_exception_field_type *ps;
478 double_equivalence kluge;
479 unpacked u;
481 *ps = 0; /* Initialize to no floating-point
482 * exceptions. */
483 kluge.f.msw.sign = pd->sign ? 1 : 0;
484 switch (pd->fpclass) {
485 case fp_zero:
486 kluge.f.msw.exponent = 0;
487 kluge.f.msw.significand = 0;
488 kluge.f.significand2 = 0;
489 break;
490 case fp_infinity:
491 kluge.f.msw.exponent = 0x7ff;
492 kluge.f.msw.significand = 0;
493 kluge.f.significand2 = 0;
494 break;
495 case fp_quiet:
496 kluge.f.msw.exponent = 0x7ff;
497 kluge.f.msw.significand = 0xfffff;
498 kluge.f.significand2 = 0xffffffff;
499 break;
500 case fp_signaling:
501 kluge.f.msw.exponent = 0x7ff;
502 kluge.f.msw.significand = 0x7ffff;
503 kluge.f.significand2 = 0xffffffff;
504 break;
505 default:
506 if (pd->exponent > DOUBLE_MAXE) { /* Guaranteed overflow. */
507 u.sign = pd->sign == 0 ? 0 : 1;
508 u.fpclass = fp_normal;
509 u.exponent = 0x000fffff;
510 u.significand[0] = 0x80000000;
511 } else if (pd->exponent >= -DOUBLE_MAXE) { /* Guaranteed in range. */
512 goto inrange;
513 } else if (pd->exponent <= (-DOUBLE_MAXE - DECIMAL_STRING_LENGTH)) { /* Guaranteed deep
514 * underflow. */
515 goto underflow;
516 } else { /* Deep underflow possible, depending on
517 * string length. */
518 int i;
520 for (i = 0; (pd->ds[i] != 0) && (i < (-pd->exponent - DOUBLE_MAXE)); i++);
521 if (i < (-pd->exponent - DOUBLE_MAXE)) { /* Deep underflow */
522 underflow:
523 u.sign = pd->sign == 0 ? 0 : 1;
524 u.fpclass = fp_normal;
525 u.exponent = -0x000fffff;
526 u.significand[0] = 0x80000000;
527 } else {/* In range. */
528 inrange:
529 decimal_to_unpacked(&u, pd, 53);
532 _fp_current_exceptions = 0;
533 _fp_current_direction = pm->rd;
534 _pack_double(&u, &kluge.x);
535 *ps = _fp_current_exceptions;
537 *px = kluge.x;
540 void
541 decimal_to_extended(px, pm, pd, ps)
542 extended *px;
543 decimal_mode *pm;
544 decimal_record *pd;
545 fp_exception_field_type *ps;
547 extended_equivalence kluge;
548 unpacked u;
550 *ps = 0; /* Initialize to no floating-point
551 * exceptions. */
552 kluge.f.msw.sign = pd->sign ? 1 : 0;
553 switch (pd->fpclass) {
554 case fp_zero:
555 kluge.f.msw.exponent = 0;
556 kluge.f.significand = 0;
557 kluge.f.significand2 = 0;
558 break;
559 case fp_infinity:
560 kluge.f.msw.exponent = 0x7fff;
561 kluge.f.significand = 0;
562 kluge.f.significand2 = 0;
563 break;
564 case fp_quiet:
565 kluge.f.msw.exponent = 0x7fff;
566 kluge.f.significand = 0xffffffff;
567 kluge.f.significand2 = 0xffffffff;
568 break;
569 case fp_signaling:
570 kluge.f.msw.exponent = 0x7fff;
571 kluge.f.significand = 0x3fffffff;
572 kluge.f.significand2 = 0xffffffff;
573 break;
574 default:
575 if (pd->exponent > EXTENDED_MAXE) { /* Guaranteed overflow. */
576 u.sign = pd->sign == 0 ? 0 : 1;
577 u.fpclass = fp_normal;
578 u.exponent = 0x000fffff;
579 u.significand[0] = 0x80000000;
580 } else if (pd->exponent >= -EXTENDED_MAXE) { /* Guaranteed in range. */
581 goto inrange;
582 } else if (pd->exponent <= (-EXTENDED_MAXE - DECIMAL_STRING_LENGTH)) { /* Guaranteed deep
583 * underflow. */
584 goto underflow;
585 } else { /* Deep underflow possible, depending on
586 * string length. */
587 int i;
589 for (i = 0; (pd->ds[i] != 0) && (i < (-pd->exponent - EXTENDED_MAXE)); i++);
590 if (i < (-pd->exponent - EXTENDED_MAXE)) { /* Deep underflow */
591 underflow:
592 u.sign = pd->sign == 0 ? 0 : 1;
593 u.fpclass = fp_normal;
594 u.exponent = -0x000fffff;
595 u.significand[0] = 0x80000000;
596 } else {/* In range. */
597 inrange:
598 decimal_to_unpacked(&u, pd, 64);
601 _fp_current_exceptions = 0;
602 _fp_current_direction = pm->rd;
603 _fp_current_precision = fp_extended;
604 _pack_extended(&u, px);
605 *ps = _fp_current_exceptions;
606 return;
608 (*px)[0] = kluge.x[0];
609 (*px)[1] = kluge.x[1];
610 (*px)[2] = kluge.x[2];
613 void
614 decimal_to_quadruple(px, pm, pd, ps)
615 quadruple *px;
616 decimal_mode *pm;
617 decimal_record *pd;
618 fp_exception_field_type *ps;
620 quadruple_equivalence kluge;
621 unpacked u;
622 int i;
624 *ps = 0; /* Initialize to no floating-point
625 * exceptions. */
626 kluge.f.msw.sign = pd->sign ? 1 : 0;
627 switch (pd->fpclass) {
628 case fp_zero:
629 kluge.f.msw.exponent = 0;
630 kluge.f.msw.significand = 0;
631 kluge.f.significand2 = 0;
632 kluge.f.significand3 = 0;
633 kluge.f.significand4 = 0;
634 break;
635 case fp_infinity:
636 kluge.f.msw.exponent = 0x7fff;
637 kluge.f.msw.significand = 0;
638 kluge.f.significand2 = 0;
639 kluge.f.significand3 = 0;
640 kluge.f.significand4 = 0;
641 break;
642 case fp_quiet:
643 kluge.f.msw.exponent = 0x7fff;
644 kluge.f.msw.significand = 0xffff;
645 kluge.f.significand2 = 0xffffffff;
646 kluge.f.significand3 = 0xffffffff;
647 kluge.f.significand4 = 0xffffffff;
648 break;
649 case fp_signaling:
650 kluge.f.msw.exponent = 0x7fff;
651 kluge.f.msw.significand = 0x7fff;
652 kluge.f.significand2 = 0xffffffff;
653 kluge.f.significand3 = 0xffffffff;
654 kluge.f.significand4 = 0xffffffff;
655 break;
656 default:
657 if (pd->exponent > QUAD_MAXE) { /* Guaranteed overflow. */
658 u.sign = pd->sign == 0 ? 0 : 1;
659 u.fpclass = fp_normal;
660 u.exponent = 0x000fffff;
661 u.significand[0] = 0x80000000;
662 } else if (pd->exponent >= -QUAD_MAXE) { /* Guaranteed in range. */
663 goto inrange;
664 } else if (pd->exponent <= (-QUAD_MAXE - DECIMAL_STRING_LENGTH)) { /* Guaranteed deep
665 * underflow. */
666 goto underflow;
667 } else { /* Deep underflow possible, depending on
668 * string length. */
670 for (i = 0; (pd->ds[i] != 0) && (i < (-pd->exponent - QUAD_MAXE)); i++);
671 if (i < (-pd->exponent - QUAD_MAXE)) { /* Deep underflow */
672 underflow:
673 u.sign = pd->sign == 0 ? 0 : 1;
674 u.fpclass = fp_normal;
675 u.exponent = -0x000fffff;
676 u.significand[0] = 0x80000000;
677 } else {/* In range. */
678 inrange:
679 decimal_to_unpacked(&u, pd, 113);
682 _fp_current_exceptions = 0;
683 _fp_current_direction = pm->rd;
684 _pack_quadruple(&u, px);
685 *ps = _fp_current_exceptions;
686 return;
688 #ifdef __STDC__
689 *px = kluge.x;
690 #else
691 for (i = 0; i < 4; i++)
692 px->u[i] = kluge.x.u[i];
693 #endif