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