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