xref: /titanic_52/usr/src/lib/libc/inc/base_conversion.h (revision 1a7c1b724419d3cb5fa6eea75123c6b2060ba31b)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <errno.h>
30 #include <floatingpoint.h>
31 #include <sys/isa_defs.h>
32 
33 /*
34  * Common constants, types, and declarations for floating point
35  * base conversion
36  */
37 
38 /* PRIVATE CONSTANTS	 */
39 
40 /* exponent bias */
41 #define	SINGLE_BIAS	  127
42 #define	DOUBLE_BIAS	 1023
43 #define	EXTENDED_BIAS	16383
44 #define	QUAD_BIAS	16383
45 
46 
47 /* PRIVATE TYPES */
48 
49 /*
50  * Unpacked binary floating point format.  The binary point lies
51  * to the right of the most significant bit in significand[0].
52  * The exponent is unbiased.  The significand array is long enough
53  * that the last word never contains any bits we need to keep,
54  * just rounding information.
55  */
56 
57 #define	UNPACKED_SIZE	5
58 
59 typedef struct {
60 	int		sign;
61 	enum fp_class_type fpclass;
62 	int		exponent;
63 	unsigned	significand[UNPACKED_SIZE];
64 } unpacked;
65 
66 /*
67  * Packed binary floating point formats.  The *_msw structure
68  * corresponds to the most significant word.
69  */
70 
71 #ifdef _LITTLE_ENDIAN
72 
73 typedef struct {
74 	unsigned	significand:23;
75 	unsigned	exponent:8;
76 	unsigned	sign:1;
77 } single_msw;
78 
79 typedef struct {
80 	unsigned	significand:20;
81 	unsigned	exponent:11;
82 	unsigned	sign:1;
83 } double_msw;
84 
85 typedef struct {
86 	unsigned	exponent:15;
87 	unsigned	sign:1;
88 	unsigned	unused:16;
89 } extended_msw;
90 
91 typedef struct {
92 	unsigned	significand:16;
93 	unsigned	exponent:15;
94 	unsigned	sign:1;
95 } quadruple_msw;
96 
97 typedef struct {
98 	single_msw	msw;
99 } single_formatted;
100 
101 typedef struct {
102 	unsigned	significand2;
103 	double_msw	msw;
104 } double_formatted;
105 
106 typedef struct {
107 	unsigned	significand2;
108 	unsigned	significand;
109 	extended_msw	msw;
110 } extended_formatted;
111 
112 typedef struct {
113 	unsigned	significand4;
114 	unsigned	significand3;
115 	unsigned	significand2;
116 	quadruple_msw	msw;
117 } quadruple_formatted;
118 
119 #else
120 
121 typedef struct {
122 	unsigned	sign:1;
123 	unsigned	exponent:8;
124 	unsigned	significand:23;
125 } single_msw;
126 
127 typedef struct {
128 	unsigned	sign:1;
129 	unsigned	exponent:11;
130 	unsigned	significand:20;
131 } double_msw;
132 
133 typedef struct {
134 	unsigned	sign:1;
135 	unsigned	exponent:15;
136 	unsigned	unused:16;
137 } extended_msw;
138 
139 typedef struct {
140 	unsigned	sign:1;
141 	unsigned	exponent:15;
142 	unsigned	significand:16;
143 } quadruple_msw;
144 
145 typedef struct {
146 	single_msw	msw;
147 } single_formatted;
148 
149 typedef struct {
150 	double_msw	msw;
151 	unsigned	significand2;
152 } double_formatted;
153 
154 typedef struct {
155 	extended_msw	msw;
156 	unsigned	significand;
157 	unsigned	significand2;
158 } extended_formatted;
159 
160 typedef struct {
161 	quadruple_msw   msw;
162 	unsigned	significand2;
163 	unsigned	significand3;
164 	unsigned	significand4;
165 } quadruple_formatted;
166 
167 #endif
168 
169 typedef union {
170 	single_formatted f;
171 	single		x;
172 } single_equivalence;
173 
174 typedef union {
175 	double_formatted f;
176 	double		x;
177 } double_equivalence;
178 
179 typedef union {
180 	extended_formatted f;
181 	extended	x;
182 } extended_equivalence;
183 
184 typedef union {
185 	quadruple_formatted f;
186 	quadruple	x;
187 } quadruple_equivalence;
188 
189 /*
190  * Multiple precision floating point type.  This type is suitable
191  * for representing positive floating point numbers of variable
192  * precision in either binary or decimal.  The bsignificand array
193  * holds the digits of a multi-word integer, stored least significant
194  * digit first, in either radix 2^16 or 10^4.  blength is the
195  * length of the significand array.  bexponent is a power of two
196  * or ten, so that the value represented is
197  *
198  *   2^(bexponent) * sum (bsignificand[i] * 2^(i*16))
199  *
200  * if binary, or
201  *
202  *   10^(bexponent) * sum (bsignificand[i] * 10^(i*4))
203  *
204  * if decimal, where the sum runs from i = 0 to blength - 1.
205  * (Whether the representation is binary or decimal is implied
206  * from context.)  bsize indicates the size of the significand
207  * array and may be larger than _BIG_FLOAT_SIZE if storage has
208  * been allocated at runtime.
209  */
210 
211 #define	_BIG_FLOAT_SIZE	(DECIMAL_STRING_LENGTH/2)
212 
213 typedef struct {
214 	unsigned short  bsize;
215 	unsigned short  blength;
216 	short int	bexponent;
217 	unsigned short	bsignificand[_BIG_FLOAT_SIZE];
218 } _big_float;
219 
220 /* structure for storing IEEE modes and status flags */
221 typedef struct {
222 	int	status, mode;
223 } __ieee_flags_type;
224 
225 
226 /* PRIVATE GLOBAL VARIABLES */
227 
228 /*
229  * Flags to indicate whether any NaNs or infinities have been read
230  * or written.  These are exported solely for the use of the old
231  * Sun Fortran runtime library.  Once that becomes obsolete, these
232  * can be removed.
233  */
234 extern int *_thr_get_inf_read(void);
235 extern int *_thr_get_inf_written(void);
236 extern int *_thr_get_nan_read(void);
237 extern int *_thr_get_nan_written(void);
238 
239 #define	__inf_read		(*(int *)_thr_get_inf_read())
240 #define	__inf_written		(*(int *)_thr_get_inf_written())
241 #define	__nan_read		(*(int *)_thr_get_nan_read())
242 #define	__nan_written		(*(int *)_thr_get_nan_written())
243 
244 /*
245  * Powers of 5 in base 2**16 and powers of 2 in base 10**4.
246  *
247  * __tbl_10_small_digits	contains
248  *	5**0,
249  *	5**1, ...
250  *	5**__TBL_10_SMALL_SIZE-1
251  * __tbl_10_big_digits		contains
252  *	5**0,
253  *	5**__TBL_10_SMALL_SIZE, ...
254  *	5**__TBL_10_SMALL_SIZE*(__TBL_10_BIG_SIZE-1)
255  * __tbl_10_huge_digits		contains
256  *	5**0,
257  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE, ...
258  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*(__TBL_10_HUGE_SIZE-1)
259  *
260  * so that any power of 5 from 5**0 to
261  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*__TBL_10_HUGE_SIZE
262  * can be represented as a product of at most three table entries.
263  *
264  * Similarly any power of 2 from 2**0 to
265  *	2**__TBL_2_SMALL_SIZE*__TBL_2_BIG_SIZE*__TBL_2_HUGE_SIZE
266  * can be represented as a product of at most three table entries.
267  *
268  * Since the powers vary greatly in size, the tables are condensed:
269  * entry i in table x is stored in
270  *	x_digits[x_start[i]] (least significant)
271  * through
272  *	x_digits[x_start[i+1]-1] (most significant)
273  */
274 
275 #define	__TBL_10_SMALL_SIZE	64
276 #define	__TBL_10_BIG_SIZE	16
277 #define	__TBL_10_HUGE_SIZE	6
278 
279 extern const unsigned short
280 	__tbl_10_small_digits[], __tbl_10_small_start[],
281 	__tbl_10_big_digits[], __tbl_10_big_start[],
282 	__tbl_10_huge_digits[], __tbl_10_huge_start[];
283 
284 #define	__TBL_2_SMALL_SIZE	176
285 #define	__TBL_2_BIG_SIZE	16
286 #define	__TBL_2_HUGE_SIZE	6
287 
288 extern const unsigned short
289 	__tbl_2_small_digits[], __tbl_2_small_start[],
290 	__tbl_2_big_digits[], __tbl_2_big_start[],
291 	__tbl_2_huge_digits[], __tbl_2_huge_start[];
292 
293 /*
294  * Powers of ten.  For i = 0, 1, ..., __TBL_TENS_MAX, __tbl_tens[i]
295  * = 10^i rounded to double precision.  (10^i is representable exactly
296  * in double precision for i <= __TBL_TENS_EXACT.)
297  */
298 
299 #define	__TBL_TENS_EXACT	22
300 #define	__TBL_TENS_MAX		49
301 
302 extern const double __tbl_tens[];
303 
304 
305 /* PRIVATE FUNCTIONS */
306 
307 extern void __base_conversion_set_exception(fp_exception_field_type);
308 
309 extern void __four_digits_quick(unsigned short, char *);
310 
311 extern int __fast_double_to_decimal(double *dd, decimal_mode *pm,
312 		decimal_record *pd, fp_exception_field_type *ps);
313 
314 extern void __pack_single(unpacked *, single *, enum fp_direction_type,
315 		fp_exception_field_type *);
316 extern void __pack_double(unpacked *, double *, enum fp_direction_type,
317 		fp_exception_field_type *);
318 extern void __pack_extended(unpacked *, extended *, enum fp_direction_type,
319 		fp_exception_field_type *);
320 extern void __pack_quadruple(unpacked *, quadruple *,
321 		enum fp_direction_type, fp_exception_field_type *);
322 
323 extern void __infnanstring(enum fp_class_type cl, int ndigits, char *buf);
324 
325 extern void __big_float_times_power(_big_float *pbf, int mult, int n,
326 		int precision, _big_float **pnewbf);
327 
328 extern void __get_ieee_flags(__ieee_flags_type *);
329 extern void __set_ieee_flags(__ieee_flags_type *);
330 
331 extern double __mul_set(double, double, int *);
332 extern double __div_set(double, double, int *);
333 extern double __dabs(double *);
334 
335 #if defined(sparc) || defined(__sparc)
336 extern enum fp_direction_type _QgetRD(void);
337 #endif
338