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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Conversion from binary to decimal floating point
33 #include "base_conversion.h"
36 * Any sensible programmer would inline the following routine where
37 * it is used below. Unfortunately, the Sun SPARC compilers are not
38 * consistent in generating efficient code for this, so inlining it
39 * as written can cause the *_to_decimal functions to take twice as
42 * We might be tempted, then, to rewrite the source to match the most
43 * efficient code the compilers generate and inline that. Alas, the
44 * most efficient code on SPARC uses 32x32->64 bit multiply, which
45 * can't be expressed directly in source code. We could use long long,
46 * which would imply 64x64->64 bit multiply; this would work perfectly
47 * well on SPARC in v8plus mode. But as of Solaris 10, libc for SPARC
48 * is still built in v8 mode, and of course, x86 is another story.
50 * We could also choose to use an inline template to get the most
51 * efficient code without incurring the full cost of a function call.
52 * Since I expect that would not buy much performance gain, and I
53 * prefer to avoid using inline templates for things that can be
54 * written in a perfectly straightforward way in C, I've settled
55 * for this implementation. I hope that someday the compilers will
56 * get less flaky and/or someone will come up with a better way to
60 __quorem10000(unsigned int x
, unsigned short *pr
)
67 * Convert the integer part of a nonzero base-2^16 _big_float *pb
68 * to base 10^4 in **ppd. The converted value is accurate to nsig
69 * significant digits. On exit, *sticky is nonzero if *pb had a
70 * nonzero fractional part. If pb->exponent > 0 and **ppd is not
71 * large enough to hold the final converted value (i.e., the con-
72 * verted significand scaled by 2^pb->exponent), then on exit,
73 * *ppd will point to a newly allocated _big_float, which must be
74 * freed by the caller. (The number of significant digits we need
75 * should fit in pd, but __big_float_times_power may allocate new
76 * storage anyway because we could be multiplying by as much as
77 * 2^16271, which would require more than 4000 digits.)
79 * This routine does not check that **ppd is large enough to hold
80 * the result of converting the significand of *pb.
83 __big_binary_to_big_decimal(_big_float
*pb
, int nsig
, _big_float
**ppd
,
92 /* convert pb a digit at a time, most significant first */
93 if (pb
->bexponent
+ ((pb
->blength
- 1) << 4) >= 0) {
94 carry
= pb
->bsignificand
[pb
->blength
- 1];
95 pd
->bsignificand
[1] = __quorem10000(carry
,
96 &pd
->bsignificand
[0]);
97 len
= (pd
->bsignificand
[1])? 2 : 1;
98 for (i
= pb
->blength
- 2; i
>= 0 &&
99 pb
->bexponent
+ (i
<< 4) >= 0; i
--) {
100 /* multiply pd by 2^16 and add next digit */
101 carry
= pb
->bsignificand
[i
];
102 for (j
= 0; j
< len
; j
++) {
103 carry
+= (unsigned int)pd
->bsignificand
[j
]
105 carry
= __quorem10000(carry
,
106 &pd
->bsignificand
[j
]);
109 carry
= __quorem10000(carry
,
110 &pd
->bsignificand
[j
]);
120 /* convert any partial digit */
121 if (i
>= 0 && pb
->bexponent
+ (i
<< 4) > -16) {
122 s
= pb
->bexponent
+ (i
<< 4) + 16;
123 /* multiply pd by 2^s and add partial digit */
124 carry
= pb
->bsignificand
[i
] >> (16 - s
);
125 for (j
= 0; j
< len
; j
++) {
126 carry
+= (unsigned int)pd
->bsignificand
[j
] << s
;
127 carry
= __quorem10000(carry
, &pd
->bsignificand
[j
]);
130 carry
= __quorem10000(carry
, &pd
->bsignificand
[j
]);
134 s
= pb
->bsignificand
[i
] & ((1 << (16 - s
)) - 1);
143 /* continue accumulating sticky flag */
145 s
|= pb
->bsignificand
[i
--];
148 if (pb
->bexponent
> 0) {
149 /* scale pd by 2^pb->bexponent */
150 __big_float_times_power(pd
, 2, pb
->bexponent
, nsig
, ppd
);
155 * Convert a base-10^4 _big_float *pf to a decimal string in *pd,
156 * rounding according to the modes in *pm and recording any exceptions
157 * in *ps. If sticky is nonzero, then additional nonzero digits are
158 * assumed to follow those in *pf. pd->sign must have already been
159 * filled in, and pd->fpclass is not modified. The resulting string
160 * is stored in pd->ds, terminated by a null byte. The length of this
161 * string is stored in pd->ndigits, and the corresponding exponent
162 * is stored in pd->exponent. If the converted value is not exact,
163 * the inexact flag is set in *ps.
165 * When pm->df == fixed_form, we may discover that the result would
166 * have more than DECIMAL_STRING_LENGTH - 1 digits. In this case,
167 * we put DECIMAL_STRING_LENGTH - 1 digits into *pd, adjusting both
168 * the exponent and the decimal place at which the value is rounded
169 * as need be, and we set the overflow flag in *ps. (Raising overflow
170 * is a bug, but we have to do it to maintain backward compatibility.)
172 * *pf may be modified.
175 __big_decimal_to_string(_big_float
*pf
, int sticky
, decimal_mode
*pm
,
176 decimal_record
*pd
, fp_exception_field_type
*ps
)
179 int e
, er
, efirst
, elast
, i
, is
, j
;
182 /* set e = floor(log10(*pf)) */
185 e
= pf
->bexponent
= -DECIMAL_STRING_LENGTH
- 2;
187 e
= pf
->bexponent
+ (i
<< 2);
188 d
= pf
->bsignificand
[i
];
198 * Determine the power of ten after which to round and the
199 * powers corresponding to the first and last digits desired
202 if (pm
->df
== fixed_form
) {
206 efirst
= (e
>= 0)? e
: -1;
209 efirst
= (e
>= er
)? e
: ((er
> 0)? er
- 1 : 0);
213 /* check for possible overflow of pd->ds */
214 if (efirst
- elast
>= DECIMAL_STRING_LENGTH
- 1) {
216 elast
= e
- DECIMAL_STRING_LENGTH
+ 2;
219 *ps
|= 1 << fp_overflow
;
224 elast
= er
= e
- pm
->ndigits
+ 1;
227 /* retrieve digits down to the (er - 1) place */
229 for (e
= efirst
; e
>= pf
->bexponent
+ (pf
->blength
<< 2) &&
234 j
= 3 - ((e
- pf
->bexponent
) & 3);
235 if (j
> 0 && e
>= er
- 1) {
236 __four_digits_quick(pf
->bsignificand
[i
], s
);
237 while (j
<= 3 && e
>= er
- 1) {
238 pd
->ds
[is
++] = s
[j
++];
242 sticky
|= (s
[j
++] - '0');
246 while ((i
| (e
- er
- 2)) >= 0) { /* i >= 0 && e >= er + 2 */
247 __four_digits_quick(pf
->bsignificand
[i
], pd
->ds
+ is
);
255 __four_digits_quick(pf
->bsignificand
[i
], s
);
256 for (j
= 0; e
>= er
- 1; j
++) {
261 sticky
|= (s
[j
++] - '0');
265 while (e
-- >= er
- 1)
269 /* collect rounding information */
270 round
= pd
->ds
[--is
];
272 sticky
|= pf
->bsignificand
[i
--];
274 /* add more trailing zeroes if need be */
275 for (e
= er
- 1; e
>= elast
; e
--)
278 pd
->exponent
= elast
;
283 if (round
== '0' && sticky
== 0)
286 *ps
|= 1 << fp_inexact
;
290 if (round
< '5' || (round
== '5' && sticky
== 0 &&
291 (is
<= 0 || (pd
->ds
[is
- 1] & 1) == 0)))
310 for (i
= efirst
- er
; i
>= 0 && pd
->ds
[i
] == '9'; i
--)
315 /* rounding carry out has occurred */
317 if (pm
->df
== floating_form
) {
319 } else if (is
== DECIMAL_STRING_LENGTH
- 1) {
321 *ps
|= 1 << fp_overflow
;
333 * Convert a binary floating point value represented by *pf to a
334 * decimal record *pd according to the modes in *pm. Any exceptions
335 * incurred are passed back via *ps.
338 __bigfloat_to_decimal(_big_float
*bf
, decimal_mode
*pm
, decimal_record
*pd
,
339 fp_exception_field_type
*ps
)
341 _big_float
*pbf
, *pbd
, d
;
342 int sticky
, powten
, sigbits
, sigdigits
, i
;
345 * If pm->ndigits is too large or too small, set the overflow
346 * flag in *ps and do nothing. (Raising overflow is a bug,
347 * but we have to do it to maintain backward compatibility.)
349 if (pm
->ndigits
>= DECIMAL_STRING_LENGTH
|| pm
->ndigits
<=
350 ((pm
->df
== floating_form
)? 0 : -DECIMAL_STRING_LENGTH
)) {
351 *ps
= 1 << fp_overflow
;
358 /* pre-scale to get the digits we want into the integer part */
359 if (pm
->df
== fixed_form
) {
361 if (pm
->ndigits
>= 0 && bf
->bexponent
< 0) {
363 * Scale by 10^min(-bf->bexponent, pm->ndigits + 1).
365 powten
= pm
->ndigits
+ 1;
366 if (powten
> -bf
->bexponent
)
367 powten
= -bf
->bexponent
;
369 * Take sigbits large enough to get all integral
372 sigbits
= bf
->bexponent
+ (bf
->blength
<< 4) +
373 (((powten
* 217706) + 65535) >> 16);
376 __big_float_times_power(bf
, 10, powten
, sigbits
, &pbf
);
378 sigdigits
= DECIMAL_STRING_LENGTH
+ 1;
381 if (bf
->bexponent
< 0) {
382 /* i is a lower bound on log2(x) */
383 i
= bf
->bexponent
+ ((bf
->blength
- 1) << 4);
384 if (i
<= 0 || ((i
* 19728) >> 16) < pm
->ndigits
+ 1) {
386 * Scale by 10^min(-bf->bexponent,
387 * pm->ndigits + 1 + u) where u is
388 * an upper bound on -log10(x).
390 powten
= pm
->ndigits
+ 1;
392 powten
+= ((-i
* 19729) + 65535) >> 16;
394 powten
-= (i
* 19728) >> 16;
395 if (powten
> -bf
->bexponent
)
396 powten
= -bf
->bexponent
;
398 * Take sigbits large enough to get
399 * all integral digits correct.
402 (((powten
* 217706) + 65535) >> 16);
403 __big_float_times_power(bf
, 10, powten
,
407 sigdigits
= pm
->ndigits
+ 2;
410 /* convert to base 10^4 */
411 d
.bsize
= _BIG_FLOAT_SIZE
;
413 __big_binary_to_big_decimal(pbf
, sigdigits
, &pbd
, &sticky
);
415 /* adjust pbd->bexponent based on the scale factor above */
416 pbd
->bexponent
-= powten
;
418 /* convert to ASCII */
419 __big_decimal_to_string(pbd
, sticky
, pm
, pd
, ps
);
422 (void) free((void *)pbf
);
424 (void) free((void *)pbd
);
427 /* remove trailing zeroes from the significand of p */
429 __shorten(_big_float
*p
)
431 int length
= p
->blength
;
434 /* count trailing zeros */
435 for (zeros
= 0; zeros
< length
&& p
->bsignificand
[zeros
] == 0; zeros
++)
439 p
->bexponent
+= zeros
<< 4;
440 for (i
= 0; i
< length
; i
++)
441 p
->bsignificand
[i
] = p
->bsignificand
[i
+ zeros
];
447 * Unpack a normal or subnormal double into a _big_float.
450 __double_to_bigfloat(double *px
, _big_float
*pf
)
452 double_equivalence
*x
;
454 x
= (double_equivalence
*)px
;
455 pf
->bsize
= _BIG_FLOAT_SIZE
;
456 pf
->bexponent
= x
->f
.msw
.exponent
- DOUBLE_BIAS
- 52;
458 pf
->bsignificand
[0] = x
->f
.significand2
& 0xffff;
459 pf
->bsignificand
[1] = x
->f
.significand2
>> 16;
460 pf
->bsignificand
[2] = x
->f
.msw
.significand
& 0xffff;
461 pf
->bsignificand
[3] = x
->f
.msw
.significand
>> 16;
462 if (x
->f
.msw
.exponent
== 0) {
464 while (pf
->bsignificand
[pf
->blength
- 1] == 0)
467 pf
->bsignificand
[3] += 0x10;
473 * Unpack a normal or subnormal extended into a _big_float.
476 __extended_to_bigfloat(extended
*px
, _big_float
*pf
)
478 extended_equivalence
*x
;
480 x
= (extended_equivalence
*)px
;
481 pf
->bsize
= _BIG_FLOAT_SIZE
;
482 pf
->bexponent
= x
->f
.msw
.exponent
- EXTENDED_BIAS
- 63;
484 pf
->bsignificand
[0] = x
->f
.significand2
& 0xffff;
485 pf
->bsignificand
[1] = x
->f
.significand2
>> 16;
486 pf
->bsignificand
[2] = x
->f
.significand
& 0xffff;
487 pf
->bsignificand
[3] = x
->f
.significand
>> 16;
488 if (x
->f
.msw
.exponent
== 0) {
490 while (pf
->bsignificand
[pf
->blength
- 1] == 0)
497 * Unpack a normal or subnormal quad into a _big_float.
500 __quadruple_to_bigfloat(quadruple
*px
, _big_float
*pf
)
502 quadruple_equivalence
*x
;
504 x
= (quadruple_equivalence
*)px
;
505 pf
->bsize
= _BIG_FLOAT_SIZE
;
506 pf
->bexponent
= x
->f
.msw
.exponent
- QUAD_BIAS
- 112;
507 pf
->bsignificand
[0] = x
->f
.significand4
& 0xffff;
508 pf
->bsignificand
[1] = x
->f
.significand4
>> 16;
509 pf
->bsignificand
[2] = x
->f
.significand3
& 0xffff;
510 pf
->bsignificand
[3] = x
->f
.significand3
>> 16;
511 pf
->bsignificand
[4] = x
->f
.significand2
& 0xffff;
512 pf
->bsignificand
[5] = x
->f
.significand2
>> 16;
513 pf
->bsignificand
[6] = x
->f
.msw
.significand
;
514 if (x
->f
.msw
.exponent
== 0) {
517 while (pf
->bsignificand
[pf
->blength
- 1] == 0)
521 pf
->bsignificand
[7] = 1;
526 /* PUBLIC ROUTINES */
529 single_to_decimal(single
*px
, decimal_mode
*pm
, decimal_record
*pd
,
530 fp_exception_field_type
*ps
)
532 single_equivalence
*kluge
;
534 fp_exception_field_type ef
;
537 kluge
= (single_equivalence
*)px
;
538 pd
->sign
= kluge
->f
.msw
.sign
;
540 /* decide what to do based on the class of x */
541 if (kluge
->f
.msw
.exponent
== 0) { /* 0 or subnormal */
542 if (kluge
->f
.msw
.significand
== 0) {
543 pd
->fpclass
= fp_zero
;
547 #if defined(__sparc) || defined(__amd64)
550 pd
->fpclass
= fp_subnormal
;
552 * On SPARC when nonstandard mode is enabled,
553 * or on x64 when FTZ mode is enabled, simply
554 * converting *px to double can flush a sub-
555 * normal value to zero, so we have to go
556 * through all this nonsense instead.
559 x
= (double)(i
& ~0x80000000);
562 x
*= 1.401298464324817070923730e-45; /* 2^-149 */
564 if (__fast_double_to_decimal(&x
, pm
, pd
, &ef
)) {
565 __double_to_bigfloat(&x
, &bf
);
566 __bigfloat_to_decimal(&bf
, pm
, pd
, &ef
);
569 __base_conversion_set_exception(ef
);
573 pd
->fpclass
= fp_subnormal
;
576 } else if (kluge
->f
.msw
.exponent
== 0xff) { /* inf or nan */
577 if (kluge
->f
.msw
.significand
== 0)
578 pd
->fpclass
= fp_infinity
;
579 else if (kluge
->f
.msw
.significand
>= 0x400000)
580 pd
->fpclass
= fp_quiet
;
582 pd
->fpclass
= fp_signaling
;
586 pd
->fpclass
= fp_normal
;
591 if (__fast_double_to_decimal(&x
, pm
, pd
, &ef
)) {
592 __double_to_bigfloat(&x
, &bf
);
593 __bigfloat_to_decimal(&bf
, pm
, pd
, &ef
);
596 __base_conversion_set_exception(ef
);
601 double_to_decimal(double *px
, decimal_mode
*pm
, decimal_record
*pd
,
602 fp_exception_field_type
*ps
)
604 double_equivalence
*kluge
;
606 fp_exception_field_type ef
;
608 kluge
= (double_equivalence
*)px
;
609 pd
->sign
= kluge
->f
.msw
.sign
;
611 /* decide what to do based on the class of x */
612 if (kluge
->f
.msw
.exponent
== 0) { /* 0 or subnormal */
613 if (kluge
->f
.msw
.significand
== 0 &&
614 kluge
->f
.significand2
== 0) {
615 pd
->fpclass
= fp_zero
;
619 pd
->fpclass
= fp_subnormal
;
621 } else if (kluge
->f
.msw
.exponent
== 0x7ff) { /* inf or nan */
622 if (kluge
->f
.msw
.significand
== 0 &&
623 kluge
->f
.significand2
== 0)
624 pd
->fpclass
= fp_infinity
;
625 else if (kluge
->f
.msw
.significand
>= 0x80000)
626 pd
->fpclass
= fp_quiet
;
628 pd
->fpclass
= fp_signaling
;
632 pd
->fpclass
= fp_normal
;
636 if (__fast_double_to_decimal(px
, pm
, pd
, &ef
)) {
637 __double_to_bigfloat(px
, &bf
);
638 __bigfloat_to_decimal(&bf
, pm
, pd
, &ef
);
641 __base_conversion_set_exception(ef
);
646 extended_to_decimal(extended
*px
, decimal_mode
*pm
, decimal_record
*pd
,
647 fp_exception_field_type
*ps
)
649 extended_equivalence
*kluge
;
651 fp_exception_field_type ef
;
653 kluge
= (extended_equivalence
*)px
;
654 pd
->sign
= kluge
->f
.msw
.sign
;
656 /* decide what to do based on the class of x */
657 if (kluge
->f
.msw
.exponent
== 0) { /* 0 or subnormal */
658 if ((kluge
->f
.significand
| kluge
->f
.significand2
) == 0) {
659 pd
->fpclass
= fp_zero
;
664 * x could be a pseudo-denormal, but the distinction
667 pd
->fpclass
= fp_subnormal
;
669 } else if ((kluge
->f
.significand
& 0x80000000) == 0) {
671 * In Intel's extended format, if the exponent is
672 * nonzero but the explicit integer bit is zero, this
673 * is an "unsupported format" bit pattern; treat it
674 * like a signaling NaN.
676 pd
->fpclass
= fp_signaling
;
679 } else if (kluge
->f
.msw
.exponent
== 0x7fff) { /* inf or nan */
680 if (((kluge
->f
.significand
& 0x7fffffff) |
681 kluge
->f
.significand2
) == 0)
682 pd
->fpclass
= fp_infinity
;
683 else if ((kluge
->f
.significand
& 0x7fffffff) >= 0x40000000)
684 pd
->fpclass
= fp_quiet
;
686 pd
->fpclass
= fp_signaling
;
690 pd
->fpclass
= fp_normal
;
694 __extended_to_bigfloat(px
, &bf
);
695 __bigfloat_to_decimal(&bf
, pm
, pd
, &ef
);
697 __base_conversion_set_exception(ef
);
702 quadruple_to_decimal(quadruple
*px
, decimal_mode
*pm
, decimal_record
*pd
,
703 fp_exception_field_type
*ps
)
705 quadruple_equivalence
*kluge
;
707 fp_exception_field_type ef
;
709 kluge
= (quadruple_equivalence
*)px
;
710 pd
->sign
= kluge
->f
.msw
.sign
;
712 /* decide what to do based on the class of x */
713 if (kluge
->f
.msw
.exponent
== 0) { /* 0 or subnormal */
714 if (kluge
->f
.msw
.significand
== 0 &&
715 (kluge
->f
.significand2
| kluge
->f
.significand3
|
716 kluge
->f
.significand4
) == 0) {
717 pd
->fpclass
= fp_zero
;
721 pd
->fpclass
= fp_subnormal
;
723 } else if (kluge
->f
.msw
.exponent
== 0x7fff) { /* inf or nan */
724 if (kluge
->f
.msw
.significand
== 0 &&
725 (kluge
->f
.significand2
| kluge
->f
.significand3
|
726 kluge
->f
.significand4
) == 0)
727 pd
->fpclass
= fp_infinity
;
728 else if (kluge
->f
.msw
.significand
>= 0x8000)
729 pd
->fpclass
= fp_quiet
;
731 pd
->fpclass
= fp_signaling
;
735 pd
->fpclass
= fp_normal
;
739 __quadruple_to_bigfloat(px
, &bf
);
740 __bigfloat_to_decimal(&bf
, pm
, pd
, &ef
);
742 __base_conversion_set_exception(ef
);