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
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]
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"
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.
55 d
.bsize
= _BIG_FLOAT_SIZE
;
56 _integerstring_to_big_decimal(ds
, ndigs
, nzeros
, &nzout
, &d
);
57 _big_decimal_to_big_binary(&d
, pb
);
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
):
63 (void) printf(" decimal_to_binary_integer: decimal exponent %d too large for tables ", nzout
);
65 pb
->bexponent
= 0x7fff;
67 case ((unsigned int)BIG_FLOAT_TIMES_NOMEM
):
71 (void) sprintf(bcastring
, " decimal exponent %d ", nzout
);
72 _base_conversion_abort(ENOMEM
, bcastring
);
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);
82 if (pbout
!= pb
) { /* We don't really need such
83 * a large product; the
84 * target can't be more than
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
);
98 printf(" decimal_to_binary_integer: removed %d excess digits from product \n", pbout
->blength
- allweneed
);
99 _display_big_float(pb
, 2);
101 _free_big_float(pbout
);
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
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
;
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);
137 printf(" decimal_to_binary_fraction sigbits %d twopower %d twosig %d \n",
138 nsig
, twopower
, twosig
);
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
):
144 (void) printf(" decimal_to_binary_fraction binary exponent %d too large for tables ", twopower
);
146 pb
->bexponent
= 0x7fff;
148 case ((unsigned int)BIG_FLOAT_TIMES_NOMEM
):
152 (void) sprintf(bcastring
, " binary exponent %d ", twopower
);
153 _base_conversion_abort(ENOMEM
, bcastring
);
159 printf(" decimal_to_binary_fraction large binary exponent %d needs heap buffer \n", twopower
);
161 _display_big_float(pdout
, 10);
167 if (pdout
->bexponent
<= -4) {
168 /* Have computed appropriate decimal part; now toss fraction. */
169 excess
= (-pdout
->bexponent
) / 4;
171 printf(" discard %d excess fraction digits \n", 4 * excess
);
173 for (i
= 0; (i
< excess
) && ((pdout
)->bsignificand
[i
] == 0); i
++);
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
);
185 _free_big_float(pdout
);
186 pb
->bexponent
= -twopower
;
193 decimal_to_unpacked(px
, pd
, significant_bits
)
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
;
212 px
->fpclass
= pd
->fpclass
;
213 if ((px
->fpclass
!= fp_normal
) && (px
->fpclass
!= fp_subnormal
))
215 for (length
= 0; pd
->ds
[length
] != 0; length
++);
216 if (length
== 0) { /* A zero significand slipped by. */
217 px
->fpclass
= fp_zero
;
220 /* Length contains the number of explicit digits in string. */
221 if (pd
->exponent
>= 0) {/* All integer digits. */
223 ntz
= pd
->exponent
; /* Trailing zeros. */
225 nfrac
= 0; /* No fraction digits. */
227 } else if (length
<= -pd
->exponent
) { /* No integer digits. */
232 nlz
= -pd
->exponent
- length
; /* Leading zeros. */
233 } else { /* Some integer digits, some fraction digits. */
234 ndigs
= length
+ pd
->exponent
;
237 nfrac
= -pd
->exponent
;
239 while ((pd
->ds
[ifrac
] == '0') && (nfrac
!= 0)) {
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;
254 sigint
= 16 * (bi
.blength
+ bi
.bexponent
- 1);
257 } else { /* No integer digits. */
259 bi
.bsignificand
[0] = 0;
263 frac_bits
= significant_bits
- sigint
+ 2;
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. */
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;
281 ptounpacked
= &bf
; /* Exceptional case - all fraction. */
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
288 int nmove
, leftshift
, i
, if0
;
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.
306 assert(uneeded
<= (2 * UNPACKED_SIZE
));
310 if (bi
.blength
>= uneeded
) { /* bi will overflow unpacked,
311 * so bf is just a sticky. */
312 bi
.bsignificand
[0] |= 1;
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
323 expdiff
+= leftshift
;
324 expdiff
/= 16; /* Remaining expdiff in _BIG_FLOAT_DIGITS. */
327 assert(expdiff
>= 0); /* expdiff is now equal to the size
328 * of the hole between bi and bf. */
330 nmove
= uneeded
- bi
.blength
;
331 /* nmove is the number of words to add to bi. */
334 if (nmove
> (expdiff
+ bf
.blength
))
335 nmove
= (expdiff
+ bf
.blength
);
337 printf(" increase bi by %d words to merge \n", nmove
);
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. */
346 bi
.bsignificand
[i
] = 0;
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. */
354 bi
.bsignificand
[0] |= 1; /* If non-zero found,
357 bi
.bexponent
-= 16 * nmove
;
361 ptounpacked
->bsignificand
[0] |= pd
->more
; /* Stick in any lost
365 printf(" merged bi and bf: ");
366 _display_big_float(ptounpacked
, 2);
369 _big_binary_to_unpacked(ptounpacked
, px
);
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)
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
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
402 * pm->df and pm->ndigits are never used.
407 decimal_to_single(px
, pm
, pd
, ps
)
411 fp_exception_field_type
*ps
;
413 single_equivalence kluge
;
416 *ps
= 0; /* Initialize to no floating-point
418 kluge
.f
.msw
.sign
= pd
->sign
? 1 : 0;
419 switch (pd
->fpclass
) {
421 kluge
.f
.msw
.exponent
= 0;
422 kluge
.f
.msw
.significand
= 0;
425 kluge
.f
.msw
.exponent
= 0xff;
426 kluge
.f
.msw
.significand
= 0;
429 kluge
.f
.msw
.exponent
= 0xff;
430 kluge
.f
.msw
.significand
= 0x7fffff;
433 kluge
.f
.msw
.exponent
= 0xff;
434 kluge
.f
.msw
.significand
= 0x3fffff;
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. */
444 } else if (pd
->exponent
<= (-SINGLE_MAXE
- DECIMAL_STRING_LENGTH
)) { /* Guaranteed deep
447 } else { /* Deep underflow possible, depending on
451 for (i
= 0; (pd
->ds
[i
] != 0) && (i
< (-pd
->exponent
- SINGLE_MAXE
)); i
++);
452 if (i
< (-pd
->exponent
- SINGLE_MAXE
)) { /* Deep 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. */
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
;
472 decimal_to_double(px
, pm
, pd
, ps
)
476 fp_exception_field_type
*ps
;
478 double_equivalence kluge
;
481 *ps
= 0; /* Initialize to no floating-point
483 kluge
.f
.msw
.sign
= pd
->sign
? 1 : 0;
484 switch (pd
->fpclass
) {
486 kluge
.f
.msw
.exponent
= 0;
487 kluge
.f
.msw
.significand
= 0;
488 kluge
.f
.significand2
= 0;
491 kluge
.f
.msw
.exponent
= 0x7ff;
492 kluge
.f
.msw
.significand
= 0;
493 kluge
.f
.significand2
= 0;
496 kluge
.f
.msw
.exponent
= 0x7ff;
497 kluge
.f
.msw
.significand
= 0xfffff;
498 kluge
.f
.significand2
= 0xffffffff;
501 kluge
.f
.msw
.exponent
= 0x7ff;
502 kluge
.f
.msw
.significand
= 0x7ffff;
503 kluge
.f
.significand2
= 0xffffffff;
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. */
513 } else if (pd
->exponent
<= (-DOUBLE_MAXE
- DECIMAL_STRING_LENGTH
)) { /* Guaranteed deep
516 } else { /* Deep underflow possible, depending on
520 for (i
= 0; (pd
->ds
[i
] != 0) && (i
< (-pd
->exponent
- DOUBLE_MAXE
)); i
++);
521 if (i
< (-pd
->exponent
- DOUBLE_MAXE
)) { /* Deep 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. */
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
;
541 decimal_to_extended(px
, pm
, pd
, ps
)
545 fp_exception_field_type
*ps
;
547 extended_equivalence kluge
;
550 *ps
= 0; /* Initialize to no floating-point
552 kluge
.f
.msw
.sign
= pd
->sign
? 1 : 0;
553 switch (pd
->fpclass
) {
555 kluge
.f
.msw
.exponent
= 0;
556 kluge
.f
.significand
= 0;
557 kluge
.f
.significand2
= 0;
560 kluge
.f
.msw
.exponent
= 0x7fff;
561 kluge
.f
.significand
= 0;
562 kluge
.f
.significand2
= 0;
565 kluge
.f
.msw
.exponent
= 0x7fff;
566 kluge
.f
.significand
= 0xffffffff;
567 kluge
.f
.significand2
= 0xffffffff;
570 kluge
.f
.msw
.exponent
= 0x7fff;
571 kluge
.f
.significand
= 0x3fffffff;
572 kluge
.f
.significand2
= 0xffffffff;
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. */
582 } else if (pd
->exponent
<= (-EXTENDED_MAXE
- DECIMAL_STRING_LENGTH
)) { /* Guaranteed deep
585 } else { /* Deep underflow possible, depending on
589 for (i
= 0; (pd
->ds
[i
] != 0) && (i
< (-pd
->exponent
- EXTENDED_MAXE
)); i
++);
590 if (i
< (-pd
->exponent
- EXTENDED_MAXE
)) { /* Deep 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. */
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
;
608 (*px
)[0] = kluge
.x
[0];
609 (*px
)[1] = kluge
.x
[1];
610 (*px
)[2] = kluge
.x
[2];
614 decimal_to_quadruple(px
, pm
, pd
, ps
)
618 fp_exception_field_type
*ps
;
620 quadruple_equivalence kluge
;
624 *ps
= 0; /* Initialize to no floating-point
626 kluge
.f
.msw
.sign
= pd
->sign
? 1 : 0;
627 switch (pd
->fpclass
) {
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;
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;
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;
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;
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. */
664 } else if (pd
->exponent
<= (-QUAD_MAXE
- DECIMAL_STRING_LENGTH
)) { /* Guaranteed deep
667 } else { /* Deep underflow possible, depending on
670 for (i
= 0; (pd
->ds
[i
] != 0) && (i
< (-pd
->exponent
- QUAD_MAXE
)); i
++);
671 if (i
< (-pd
->exponent
- QUAD_MAXE
)) { /* Deep 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. */
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
;
691 for (i
= 0; i
< 4; i
++)
692 px
->u
[i
] = kluge
.x
.u
[i
];