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