1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Conversion from decimal to binary floating point
29 */
30
31 #include "lint.h"
32 #include <stdlib.h>
33 #include "base_conversion.h"
34
35 /*
36 * Convert the integer part of a nonzero base-10^4 _big_float *pd
37 * to base 2^16 in **ppb. The converted value is accurate to nsig
38 * significant bits. On exit, *sticky is nonzero if *pd had a
39 * nonzero fractional part. If pd->exponent > 0 and **ppb is not
40 * large enough to hold the final converted value (i.e., the con-
41 * verted significand scaled by 10^pd->exponent), then on exit,
42 * *ppb will point to a newly allocated _big_float, which must be
43 * freed by the caller. (The number of significant bits we need
44 * should fit in pb, but __big_float_times_power may allocate new
45 * storage anyway because the exact product could require more than
46 * 16000 bits.)
47 *
48 * This routine does not check that **ppb is large enough to hold
49 * the result of converting the significand of *pd.
50 */
51 static void
__big_decimal_to_big_binary(_big_float * pd,int nsig,_big_float ** ppb,int * sticky)52 __big_decimal_to_big_binary(_big_float *pd, int nsig, _big_float **ppb,
53 int *sticky)
54 {
55 _big_float *pb;
56 int i, j, len, s;
57 unsigned int carry;
58
59 pb = *ppb;
60
61 /* convert pd a digit at a time, most significant first */
62 if (pd->bexponent + ((pd->blength - 1) << 2) >= 0) {
63 pb->bsignificand[0] = pd->bsignificand[pd->blength - 1];
64 len = 1;
65 for (i = pd->blength - 2; i >= 0 &&
66 pd->bexponent + (i << 2) >= 0; i--) {
67 /* multiply pb by 10^4 and add next digit */
68 carry = pd->bsignificand[i];
69 for (j = 0; j < len; j++) {
70 carry += (unsigned int)pb->bsignificand[j]
71 * 10000;
72 pb->bsignificand[j] = carry & 0xffff;
73 carry >>= 16;
74 }
75 if (carry)
76 pb->bsignificand[j++] = carry;
77 len = j;
78 }
79 } else {
80 i = pd->blength - 1;
81 len = 0;
82 }
83
84 /* convert any partial digit */
85 if (i >= 0 && pd->bexponent + (i << 2) > -4) {
86 s = pd->bexponent + (i << 2) + 4;
87 /* multiply pb by 10^s and add partial digit */
88 carry = pd->bsignificand[i];
89 if (s == 1) {
90 s = carry % 1000;
91 carry = carry / 1000;
92 for (j = 0; j < len; j++) {
93 carry += (unsigned int)pb->bsignificand[j]
94 * 10;
95 pb->bsignificand[j] = carry & 0xffff;
96 carry >>= 16;
97 }
98 } else if (s == 2) {
99 s = carry % 100;
100 carry = carry / 100;
101 for (j = 0; j < len; j++) {
102 carry += (unsigned int)pb->bsignificand[j]
103 * 100;
104 pb->bsignificand[j] = carry & 0xffff;
105 carry >>= 16;
106 }
107 } else {
108 s = carry % 10;
109 carry = carry / 10;
110 for (j = 0; j < len; j++) {
111 carry += (unsigned int)pb->bsignificand[j]
112 * 1000;
113 pb->bsignificand[j] = carry & 0xffff;
114 carry >>= 16;
115 }
116 }
117 if (carry)
118 pb->bsignificand[j++] = carry;
119 len = j;
120 i--;
121 } else {
122 s = 0;
123 }
124
125 pb->blength = len;
126 pb->bexponent = 0;
127
128 /* continue accumulating sticky flag */
129 while (i >= 0)
130 s |= pd->bsignificand[i--];
131 *sticky = s;
132
133 if (pd->bexponent > 0) {
134 /* scale pb by 10^pd->exponent */
135 __big_float_times_power(pb, 10, pd->bexponent, nsig, ppb);
136 }
137 }
138
139 /*
140 * Convert the decimal_record *pd to an unpacked datum *px accurately
141 * enough that *px can be rounded correctly to sigbits significant bits.
142 * (We may assume sigbits <= 113.)
143 */
144 static void
__decimal_to_unpacked(unpacked * px,decimal_record * pd,int sigbits)145 __decimal_to_unpacked(unpacked *px, decimal_record *pd, int sigbits)
146 {
147 _big_float d, b, *pbd, *pbb;
148 char *ds;
149 int ids, i, ix, exp, ndigs;
150 int sticky, powtwo, sigdigits;
151
152 px->sign = pd->sign;
153 px->fpclass = pd->fpclass;
154 ds = pd->ds;
155 ndigs = pd->ndigits;
156 exp = pd->exponent;
157
158 /* remove trailing zeroes */
159 while (ndigs > 0 && ds[ndigs - 1] == '0') {
160 exp++;
161 ndigs--;
162 }
163 if (ndigs < 1) {
164 /* nothing left */
165 px->fpclass = fp_zero;
166 return;
167 }
168
169 /* convert remaining digits to a base-10^4 _big_float */
170 d.bsize = _BIG_FLOAT_SIZE;
171 d.bexponent = exp;
172 d.blength = (ndigs + 3) >> 2;
173 i = d.blength - 1;
174 ids = ndigs - (d.blength << 2);
175 switch (ids) {
176 case -1:
177 d.bsignificand[i] = 100 * ds[ids + 1] +
178 10 * ds[ids + 2] + ds[ids + 3] - 111 * '0';
179 i--;
180 ids += 4;
181 break;
182
183 case -2:
184 d.bsignificand[i] = 10 * ds[ids + 2] + ds[ids + 3] - 11 * '0';
185 i--;
186 ids += 4;
187 break;
188
189 case -3:
190 d.bsignificand[i] = ds[ids + 3] - '0';
191 i--;
192 ids += 4;
193 break;
194 }
195 while (i >= 0) {
196 d.bsignificand[i] = 1000 * ds[ids] + 100 * ds[ids + 1] +
197 10 * ds[ids + 2] + ds[ids + 3] - 1111 * '0';
198 i--;
199 ids += 4;
200 }
201
202 pbd = &d;
203 powtwo = 0;
204
205 /* pre-scale to get the bits we want into the integer part */
206 if (exp < 0) {
207 /* i is a lower bound on log10(x) */
208 i = exp + ndigs - 1;
209 if (i <= 0 || ((i * 217705) >> 16) < sigbits + 2) {
210 /*
211 * Scale by 2^(sigbits + 2 + u) where
212 * u is an upper bound on -log2(x).
213 */
214 powtwo = sigbits + 2;
215 if (i < 0)
216 powtwo += ((-i * 217706) + 65535) >> 16;
217 else if (i > 0)
218 powtwo -= (i * 217705) >> 16;
219 /*
220 * Take sigdigits large enough to get
221 * all integral digits correct.
222 */
223 sigdigits = i + 1 + (((powtwo * 19729) + 65535) >> 16);
224 __big_float_times_power(&d, 2, powtwo, sigdigits, &pbd);
225 }
226 }
227
228 /* convert to base 2^16 */
229 b.bsize = _BIG_FLOAT_SIZE;
230 pbb = &b;
231 __big_decimal_to_big_binary(pbd, sigbits + 2, &pbb, &sticky);
232
233 /* adjust pbb->bexponent based on the scale factor above */
234 pbb->bexponent -= powtwo;
235
236 /* convert to unpacked */
237 ix = 0;
238 for (i = pbb->blength - 1; i > 0 && ix < 5; i -= 2) {
239 px->significand[ix++] = (pbb->bsignificand[i] << 16) |
240 pbb->bsignificand[i - 1];
241 }
242 if (ix < 5) {
243 /* pad with zeroes */
244 if (i == 0)
245 px->significand[ix++] = pbb->bsignificand[i] << 16;
246 while (ix < 5)
247 px->significand[ix++] = 0;
248 } else {
249 /* truncate and set a sticky bit if necessary */
250 while (i >= 0 && pbb->bsignificand[i] == 0)
251 i--;
252 if (i >= 0)
253 px->significand[4] |= 1;
254 }
255 if (sticky | pd->more)
256 px->significand[4] |= 1;
257 px->exponent = pbb->bexponent + (pbb->blength << 4) - 1;
258
259 /* normalize so the most significant bit is set */
260 while (px->significand[0] < 0x80000000u) {
261 px->significand[0] = (px->significand[0] << 1) |
262 (px->significand[1] >> 31);
263 px->significand[1] = (px->significand[1] << 1) |
264 (px->significand[2] >> 31);
265 px->significand[2] = (px->significand[2] << 1) |
266 (px->significand[3] >> 31);
267 px->significand[3] = (px->significand[3] << 1) |
268 (px->significand[4] >> 31);
269 px->significand[4] <<= 1;
270 px->exponent--;
271 }
272
273 if (pbd != &d)
274 (void) free((void *)pbd);
275 if (pbb != &b)
276 (void) free((void *)pbb);
277 }
278
279 /*
280 * Convert a string s consisting of n <= 18 ASCII decimal digits
281 * to an integer value in double precision format, and set *pe
282 * to the number of rounding errors incurred (0 or 1).
283 */
284 static double
__digits_to_double(char * s,int n,int * pe)285 __digits_to_double(char *s, int n, int *pe)
286 {
287 int i, acc;
288 double t, th, tl;
289
290 if (n <= 9) {
291 acc = s[0] - '0';
292 for (i = 1; i < n; i++) {
293 /* acc <- 10 * acc + next digit */
294 acc = (acc << 1) + (acc << 3) + s[i] - '0';
295 }
296 t = (double)acc;
297 *pe = 0;
298 } else {
299 acc = s[0] - '0';
300 for (i = 1; i < (n - 9); i++) {
301 /* acc <- 10 * acc + next digit */
302 acc = (acc << 1) + (acc << 3) + s[i] - '0';
303 }
304 th = 1.0e9 * (double)acc; /* this will be exact */
305 acc = s[n - 9] - '0';
306 for (i = n - 8; i < n; i++) {
307 /* acc <- 10 * acc + next digit */
308 acc = (acc << 1) + (acc << 3) + s[i] - '0';
309 }
310 tl = (double)acc;
311 /* add and indicate whether or not the sum is exact */
312 t = th + tl;
313 *pe = ((t - th) == tl)? 0 : 1;
314 }
315 return (t);
316 }
317
318 static union {
319 int i[2];
320 double d;
321 } C[] = {
322 #ifdef _LITTLE_ENDIAN
323 { 0x00000000, 0x3cc40000 },
324 #else
325 { 0x3cc40000, 0x00000000 }, /* 5 * 2^-53 */
326 #endif
327 };
328
329 #define five2m53 C[0].d
330
331 static int
__fast_decimal_to_single(single * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)332 __fast_decimal_to_single(single *px, decimal_mode *pm, decimal_record *pd,
333 fp_exception_field_type *ps)
334 {
335 double dds, delta, ddsplus, ddsminus, df1;
336 int n, exp, rounded, e;
337 float f1, f2;
338 __ieee_flags_type fb;
339
340 if (pm->rd != fp_nearest)
341 return (0);
342
343 exp = pd->exponent;
344 if (pd->ndigits <= 18) {
345 rounded = 0;
346 n = pd->ndigits;
347 } else {
348 rounded = 1;
349 n = 18;
350 exp += pd->ndigits - 18;
351 }
352 /*
353 * exp must be in the range of the table, and the result
354 * must not underflow or overflow.
355 */
356 if (exp < -__TBL_TENS_MAX || exp + n < -36 || exp + n > 38)
357 return (0);
358
359 __get_ieee_flags(&fb);
360 dds = __digits_to_double(pd->ds, n, &e);
361 if (e != 0)
362 rounded = 1;
363 if (exp > 0) {
364 /* small positive exponent */
365 if (exp > __TBL_TENS_EXACT)
366 rounded = 1;
367 if (rounded) {
368 dds *= __tbl_tens[exp];
369 } else {
370 dds = __mul_set(dds, __tbl_tens[exp], &e);
371 if (e)
372 rounded = 1;
373 }
374 } else if (exp < 0) {
375 /* small negative exponent */
376 if (-exp > __TBL_TENS_EXACT)
377 rounded = 1;
378 if (rounded) {
379 dds /= __tbl_tens[-exp];
380 } else {
381 dds = __div_set(dds, __tbl_tens[-exp], &e);
382 if (e)
383 rounded = 1;
384 }
385 }
386
387 /*
388 * At this point dds may have four rounding errors due to
389 * (i) truncation of pd->ds to 18 digits, (ii) inexact con-
390 * version of pd->ds to binary, (iii) scaling by a power of
391 * ten that is not exactly representable, and (iv) roundoff
392 * error in the multiplication. Below we will incur one more
393 * rounding error when we add or subtract delta and dds. We
394 * construct delta so that even after this last rounding error,
395 * ddsplus is an upper bound on the exact value and ddsminus
396 * is a lower bound. Then as long as both of these quantities
397 * round to the same single precision number, that number
398 * will be the correctly rounded single precision result.
399 * (If any rounding errors have been committed, then we must
400 * also be certain that the result can't be exact.)
401 */
402 delta = five2m53 * dds;
403 ddsplus = dds + delta;
404 ddsminus = dds - delta;
405 f1 = (float)(ddsplus);
406 f2 = (float)(ddsminus);
407 df1 = f1;
408 __set_ieee_flags(&fb);
409 if (f1 != f2)
410 return (0);
411 if (rounded) {
412 /*
413 * If ddsminus <= f1 <= ddsplus, the result might be
414 * exact; we have to convert the long way to be sure.
415 */
416 if (ddsminus <= df1 && df1 <= ddsplus)
417 return (0);
418 *ps = (1 << fp_inexact);
419 } else {
420 *ps = (df1 == dds)? 0 : (1 << fp_inexact);
421 }
422 *px = (pd->sign)? -f1 : f1;
423 return (1);
424 }
425
426 /*
427 * Attempt conversion to double using floating-point arithmetic.
428 * Return 1 if it works (at most one rounding error), 0 if it doesn't.
429 */
430 static int
__fast_decimal_to_double(double * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)431 __fast_decimal_to_double(double *px, decimal_mode *pm, decimal_record *pd,
432 fp_exception_field_type *ps)
433 {
434 double dds;
435 int e;
436 __ieee_flags_type fb;
437
438 if (pm->rd != fp_nearest || pd->ndigits > 18 || pd->exponent
439 > __TBL_TENS_EXACT || pd->exponent < -__TBL_TENS_EXACT)
440 return (0);
441
442 __get_ieee_flags(&fb);
443 dds = __digits_to_double(pd->ds, pd->ndigits, &e);
444 if (e != 0) {
445 __set_ieee_flags(&fb);
446 return (0);
447 }
448 if (pd->exponent > 0)
449 dds = __mul_set(dds, __tbl_tens[pd->exponent], &e);
450 else if (pd->exponent < 0)
451 dds = __div_set(dds, __tbl_tens[-pd->exponent], &e);
452 *px = (pd->sign)? -dds : dds;
453 *ps = (e)? (1 << fp_inexact) : 0;
454 __set_ieee_flags(&fb);
455 return (1);
456 }
457
458 /* PUBLIC FUNCTIONS */
459
460 /*
461 * The following routines convert the decimal record *pd to a floating
462 * point value *px observing the rounding mode specified in pm->rd and
463 * passing back any floating point exceptions that occur in *ps.
464 *
465 * pd->sign and pd->fpclass are always taken into account. pd->exponent
466 * and pd->ds are used when pd->fpclass is fp_normal or fp_subnormal.
467 * In these cases, pd->ds must contain a null-terminated string of one
468 * or more ASCII digits, the first of which is not zero, and pd->ndigits
469 * must equal the length of this string. If m is the integer represented
470 * by the string pd->ds, then *px will be set to a correctly rounded
471 * approximation to
472 *
473 * -1**(pd->sign) * m * 10**(pd->exponent)
474 *
475 * (If pd->more != 0 then additional nonzero digits are assumed to follow
476 * those in pd->ds, so m is effectively replaced by m + epsilon in the
477 * expression above.)
478 *
479 * For example, if pd->exponent == -2 and pd->ds holds "1234", then *px
480 * will be a correctly rounded approximation to 12.34.
481 *
482 * Note that the only mode that matters is the rounding direction pm->rd;
483 * pm->df and pm->ndigits are never used.
484 */
485
486 /* maximum decimal exponent we need to consider */
487 #define SINGLE_MAXE 47
488 #define DOUBLE_MAXE 326
489 #define EXTENDED_MAXE 4968
490 #define QUAD_MAXE 4968
491
492 void
decimal_to_single(single * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)493 decimal_to_single(single *px, decimal_mode *pm, decimal_record *pd,
494 fp_exception_field_type *ps)
495 {
496 single_equivalence *kluge;
497 unpacked u;
498 fp_exception_field_type ef;
499 int i;
500
501 /* special values */
502 kluge = (single_equivalence *)px;
503 switch (pd->fpclass) {
504 case fp_zero:
505 kluge->f.msw.sign = (pd->sign)? 1 : 0;
506 kluge->f.msw.exponent = 0;
507 kluge->f.msw.significand = 0;
508 *ps = 0;
509 return;
510
511 case fp_infinity:
512 kluge->f.msw.sign = (pd->sign)? 1 : 0;
513 kluge->f.msw.exponent = 0xff;
514 kluge->f.msw.significand = 0;
515 *ps = 0;
516 return;
517
518 case fp_quiet:
519 kluge->f.msw.sign = (pd->sign)? 1 : 0;
520 kluge->f.msw.exponent = 0xff;
521 kluge->f.msw.significand = 0x7fffff;
522 *ps = 0;
523 return;
524
525 case fp_signaling:
526 kluge->f.msw.sign = (pd->sign)? 1 : 0;
527 kluge->f.msw.exponent = 0xff;
528 kluge->f.msw.significand = 0x3fffff;
529 *ps = 0;
530 return;
531 }
532
533 /* numeric values */
534 ef = 0;
535 if (pd->exponent + pd->ndigits > SINGLE_MAXE) {
536 /* result must overflow */
537 u.sign = (pd->sign != 0);
538 u.fpclass = fp_normal;
539 u.exponent = 0x000fffff;
540 u.significand[0] = 0x80000000;
541 for (i = 1; i < UNPACKED_SIZE; i++)
542 u.significand[i] = 0;
543 } else if (pd->exponent + pd->ndigits < -SINGLE_MAXE) {
544 /* result must underflow completely */
545 u.sign = (pd->sign != 0);
546 u.fpclass = fp_normal;
547 u.exponent = -0x000fffff;
548 u.significand[0] = 0x80000000;
549 for (i = 1; i < UNPACKED_SIZE; i++)
550 u.significand[i] = 0;
551 } else {
552 /* result may be in range */
553 if (__fast_decimal_to_single(px, pm, pd, &ef) == 1) {
554 *ps = ef;
555 if (ef != 0)
556 __base_conversion_set_exception(ef);
557 return;
558 }
559 __decimal_to_unpacked(&u, pd, 24);
560 }
561 __pack_single(&u, px, pm->rd, &ef);
562 *ps = ef;
563 if (ef != 0)
564 __base_conversion_set_exception(ef);
565 }
566
567 void
decimal_to_double(double * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)568 decimal_to_double(double *px, decimal_mode *pm, decimal_record *pd,
569 fp_exception_field_type *ps)
570 {
571 double_equivalence *kluge;
572 unpacked u;
573 fp_exception_field_type ef;
574 int i;
575
576 /* special values */
577 kluge = (double_equivalence *)px;
578 switch (pd->fpclass) {
579 case fp_zero:
580 kluge->f.msw.sign = (pd->sign)? 1 : 0;
581 kluge->f.msw.exponent = 0;
582 kluge->f.msw.significand = 0;
583 kluge->f.significand2 = 0;
584 *ps = 0;
585 return;
586
587 case fp_infinity:
588 kluge->f.msw.sign = (pd->sign)? 1 : 0;
589 kluge->f.msw.exponent = 0x7ff;
590 kluge->f.msw.significand = 0;
591 kluge->f.significand2 = 0;
592 *ps = 0;
593 return;
594
595 case fp_quiet:
596 kluge->f.msw.sign = (pd->sign)? 1 : 0;
597 kluge->f.msw.exponent = 0x7ff;
598 kluge->f.msw.significand = 0xfffff;
599 kluge->f.significand2 = 0xffffffff;
600 *ps = 0;
601 return;
602
603 case fp_signaling:
604 kluge->f.msw.sign = (pd->sign)? 1 : 0;
605 kluge->f.msw.exponent = 0x7ff;
606 kluge->f.msw.significand = 0x7ffff;
607 kluge->f.significand2 = 0xffffffff;
608 *ps = 0;
609 return;
610 }
611
612 /* numeric values */
613 ef = 0;
614 if (pd->exponent + pd->ndigits > DOUBLE_MAXE) {
615 /* result must overflow */
616 u.sign = (pd->sign != 0);
617 u.fpclass = fp_normal;
618 u.exponent = 0x000fffff;
619 u.significand[0] = 0x80000000;
620 for (i = 1; i < UNPACKED_SIZE; i++)
621 u.significand[i] = 0;
622 } else if (pd->exponent + pd->ndigits < -DOUBLE_MAXE) {
623 /* result must underflow completely */
624 u.sign = (pd->sign != 0);
625 u.fpclass = fp_normal;
626 u.exponent = -0x000fffff;
627 u.significand[0] = 0x80000000;
628 for (i = 1; i < UNPACKED_SIZE; i++)
629 u.significand[i] = 0;
630 } else {
631 /* result may be in range */
632 if (__fast_decimal_to_double(px, pm, pd, &ef) == 1) {
633 *ps = ef;
634 if (ef != 0)
635 __base_conversion_set_exception(ef);
636 return;
637 }
638 __decimal_to_unpacked(&u, pd, 53);
639 }
640 __pack_double(&u, px, pm->rd, &ef);
641 *ps = ef;
642 if (ef != 0)
643 __base_conversion_set_exception(ef);
644 }
645
646 void
decimal_to_extended(extended * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)647 decimal_to_extended(extended *px, decimal_mode *pm, decimal_record *pd,
648 fp_exception_field_type *ps)
649 {
650 extended_equivalence *kluge;
651 unpacked u;
652 double_equivalence dd;
653 fp_exception_field_type ef;
654 int i;
655
656 /* special values */
657 kluge = (extended_equivalence *)px;
658 switch (pd->fpclass) {
659 case fp_zero:
660 kluge->f.msw.sign = (pd->sign)? 1 : 0;
661 kluge->f.msw.exponent = 0;
662 kluge->f.significand = 0;
663 kluge->f.significand2 = 0;
664 *ps = 0;
665 return;
666
667 case fp_infinity:
668 kluge->f.msw.sign = (pd->sign)? 1 : 0;
669 kluge->f.msw.exponent = 0x7fff;
670 kluge->f.significand = 0x80000000;
671 kluge->f.significand2 = 0;
672 *ps = 0;
673 return;
674
675 case fp_quiet:
676 kluge->f.msw.sign = (pd->sign)? 1 : 0;
677 kluge->f.msw.exponent = 0x7fff;
678 kluge->f.significand = 0xffffffff;
679 kluge->f.significand2 = 0xffffffff;
680 *ps = 0;
681 return;
682
683 case fp_signaling:
684 kluge->f.msw.sign = (pd->sign)? 1 : 0;
685 kluge->f.msw.exponent = 0x7fff;
686 kluge->f.significand = 0xbfffffff;
687 kluge->f.significand2 = 0xffffffff;
688 *ps = 0;
689 return;
690 }
691
692 /* numeric values */
693 ef = 0;
694 if (pd->exponent + pd->ndigits > EXTENDED_MAXE) {
695 /* result must overflow */
696 u.sign = (pd->sign != 0);
697 u.fpclass = fp_normal;
698 u.exponent = 0x000fffff;
699 u.significand[0] = 0x80000000;
700 for (i = 1; i < UNPACKED_SIZE; i++)
701 u.significand[i] = 0;
702 } else if (pd->exponent + pd->ndigits < -EXTENDED_MAXE) {
703 /* result must underflow completely */
704 u.sign = (pd->sign != 0);
705 u.fpclass = fp_normal;
706 u.exponent = -0x000fffff;
707 u.significand[0] = 0x80000000;
708 for (i = 1; i < UNPACKED_SIZE; i++)
709 u.significand[i] = 0;
710 } else {
711 /* result may be in range */
712 if (__fast_decimal_to_double(&dd.x, pm, pd, &ef) == 1 &&
713 ef == 0) {
714 u.sign = dd.f.msw.sign;
715 u.fpclass = fp_normal;
716 u.exponent = dd.f.msw.exponent - DOUBLE_BIAS;
717 u.significand[0] = ((0x100000 |
718 dd.f.msw.significand) << 11) |
719 (dd.f.significand2 >> 21);
720 u.significand[1] = dd.f.significand2 << 11;
721 for (i = 2; i < UNPACKED_SIZE; i++)
722 u.significand[i] = 0;
723 } else {
724 __decimal_to_unpacked(&u, pd, 64);
725 }
726 }
727 __pack_extended(&u, px, pm->rd, &ef);
728 *ps = ef;
729 if (ef != 0)
730 __base_conversion_set_exception(ef);
731 }
732
733 void
decimal_to_quadruple(quadruple * px,decimal_mode * pm,decimal_record * pd,fp_exception_field_type * ps)734 decimal_to_quadruple(quadruple *px, decimal_mode *pm, decimal_record *pd,
735 fp_exception_field_type *ps)
736 {
737 quadruple_equivalence *kluge;
738 unpacked u;
739 double_equivalence dd;
740 fp_exception_field_type ef;
741 int i;
742
743 /* special values */
744 kluge = (quadruple_equivalence *)px;
745 switch (pd->fpclass) {
746 case fp_zero:
747 kluge->f.msw.sign = (pd->sign)? 1 : 0;
748 kluge->f.msw.exponent = 0;
749 kluge->f.msw.significand = 0;
750 kluge->f.significand2 = 0;
751 kluge->f.significand3 = 0;
752 kluge->f.significand4 = 0;
753 *ps = 0;
754 return;
755
756 case fp_infinity:
757 kluge->f.msw.sign = (pd->sign)? 1 : 0;
758 kluge->f.msw.exponent = 0x7fff;
759 kluge->f.msw.significand = 0;
760 kluge->f.significand2 = 0;
761 kluge->f.significand3 = 0;
762 kluge->f.significand4 = 0;
763 *ps = 0;
764 return;
765
766 case fp_quiet:
767 kluge->f.msw.sign = (pd->sign)? 1 : 0;
768 kluge->f.msw.exponent = 0x7fff;
769 kluge->f.msw.significand = 0xffff;
770 kluge->f.significand2 = 0xffffffff;
771 kluge->f.significand3 = 0xffffffff;
772 kluge->f.significand4 = 0xffffffff;
773 *ps = 0;
774 return;
775
776 case fp_signaling:
777 kluge->f.msw.sign = (pd->sign)? 1 : 0;
778 kluge->f.msw.exponent = 0x7fff;
779 kluge->f.msw.significand = 0x7fff;
780 kluge->f.significand2 = 0xffffffff;
781 kluge->f.significand3 = 0xffffffff;
782 kluge->f.significand4 = 0xffffffff;
783 *ps = 0;
784 return;
785 }
786
787 /* numeric values */
788 ef = 0;
789 if (pd->exponent + pd->ndigits > QUAD_MAXE) {
790 /* result must overflow */
791 u.sign = (pd->sign != 0);
792 u.fpclass = fp_normal;
793 u.exponent = 0x000fffff;
794 u.significand[0] = 0x80000000;
795 for (i = 1; i < UNPACKED_SIZE; i++)
796 u.significand[i] = 0;
797 } else if (pd->exponent + pd->ndigits < -QUAD_MAXE) {
798 /* result must underflow completely */
799 u.sign = (pd->sign != 0);
800 u.fpclass = fp_normal;
801 u.exponent = -0x000fffff;
802 u.significand[0] = 0x80000000;
803 for (i = 1; i < UNPACKED_SIZE; i++)
804 u.significand[i] = 0;
805 } else {
806 /* result may be in range */
807 if (__fast_decimal_to_double(&dd.x, pm, pd, &ef) == 1 &&
808 ef == 0) {
809 u.sign = dd.f.msw.sign;
810 u.fpclass = fp_normal;
811 u.exponent = dd.f.msw.exponent - DOUBLE_BIAS;
812 u.significand[0] = ((0x100000 |
813 dd.f.msw.significand) << 11) |
814 (dd.f.significand2 >> 21);
815 u.significand[1] = dd.f.significand2 << 11;
816 for (i = 2; i < UNPACKED_SIZE; i++)
817 u.significand[i] = 0;
818 } else {
819 __decimal_to_unpacked(&u, pd, 113);
820 }
821 }
822 __pack_quadruple(&u, px, pm->rd, &ef);
823 *ps = ef;
824 if (ef != 0)
825 __base_conversion_set_exception(ef);
826 }
827