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.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include "base_conversion.h"
31 #include <sys/types.h>
35 fconvert(double arg
, int ndigits
, int *decpt
, int *sign
, char *buf
)
39 fp_exception_field_type ef
;
44 #elif defined(__i386) || defined(__amd64)
47 #error Unknown architecture
49 dm
.df
= fixed_form
; /* F format. */
50 if (ndigits
<= -DECIMAL_STRING_LENGTH
)
51 ndigits
= -DECIMAL_STRING_LENGTH
+ 1;
52 else if (ndigits
>= DECIMAL_STRING_LENGTH
)
53 ndigits
= DECIMAL_STRING_LENGTH
- 1;
54 dm
.ndigits
= ndigits
; /* Number of digits after point. */
55 double_to_decimal(&arg
, &dm
, &dr
, &ef
);
60 *decpt
= dr
.exponent
+ dr
.ndigits
;
61 for (i
= 0; i
< dr
.ndigits
; i
++)
64 * Pad with zeroes if we didn't get all the digits
67 if (ndigits
> 0 && dr
.exponent
> -ndigits
) {
68 while (i
< dr
.ndigits
+ dr
.exponent
+ ndigits
)
76 for (i
= 1; i
< ndigits
; i
++)
82 __infnanstring(dr
.fpclass
, ndigits
, buf
);
89 sfconvert(single
*arg
, int ndigits
, int *decpt
, int *sign
, char *buf
)
93 fp_exception_field_type ef
;
98 #elif defined(__i386) || defined(__amd64)
101 #error Unknown architecture
103 dm
.df
= fixed_form
; /* F format. */
104 if (ndigits
<= -DECIMAL_STRING_LENGTH
)
105 ndigits
= -DECIMAL_STRING_LENGTH
+ 1;
106 else if (ndigits
>= DECIMAL_STRING_LENGTH
)
107 ndigits
= DECIMAL_STRING_LENGTH
- 1;
108 dm
.ndigits
= ndigits
; /* Number of digits after point. */
109 single_to_decimal(arg
, &dm
, &dr
, &ef
);
111 switch (dr
.fpclass
) {
114 *decpt
= dr
.exponent
+ dr
.ndigits
;
115 for (i
= 0; i
< dr
.ndigits
; i
++)
118 * Pad with zeroes if we didn't get all the digits
121 if (ndigits
> 0 && dr
.exponent
> -ndigits
) {
122 while (i
< dr
.ndigits
+ dr
.exponent
+ ndigits
)
130 for (i
= 1; i
< ndigits
; i
++)
136 __infnanstring(dr
.fpclass
, ndigits
, buf
);
143 qfconvert(quadruple
*arg
, int ndigits
, int *decpt
, int *sign
, char *buf
)
147 fp_exception_field_type ef
;
152 #elif defined(__i386) || defined(__amd64)
155 #error Unknown architecture
157 dm
.df
= fixed_form
; /* F format. */
158 if (ndigits
<= -DECIMAL_STRING_LENGTH
)
159 ndigits
= -DECIMAL_STRING_LENGTH
+ 1;
160 else if (ndigits
>= DECIMAL_STRING_LENGTH
)
161 ndigits
= DECIMAL_STRING_LENGTH
- 1;
162 dm
.ndigits
= ndigits
; /* Number of digits after point. */
164 quadruple_to_decimal(arg
, &dm
, &dr
, &ef
);
165 #elif defined(__i386) || defined(__amd64)
166 extended_to_decimal((extended
*)arg
, &dm
, &dr
, &ef
);
168 #error Unknown architecture
171 if (ef
& (1 << fp_overflow
)) {
173 * *_to_decimal raises overflow whenever dr.ds isn't large
174 * enough to hold all the digits requested. For float and
175 * double, this can only happen when the requested format
176 * would require trailing zeroes, in which case fconvert
177 * and sfconvert just add them. For long double, the arg-
178 * ument might be large enough that even the nonzero digits
179 * would overflow dr.ds, so we punt instead. (We could
180 * distinguish these two cases, but it doesn't seem worth
181 * changing things now, particularly since no real appli-
182 * cation prints floating point numbers to 500 digits.)
188 switch (dr
.fpclass
) {
191 *decpt
= dr
.exponent
+ dr
.ndigits
;
192 for (i
= 0; i
< dr
.ndigits
; i
++)
199 for (i
= 1; i
< ndigits
; i
++)
205 __infnanstring(dr
.fpclass
, ndigits
, buf
);