xref: /titanic_51/usr/src/lib/libbc/libc/gen/common/base_conversion.h (revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae)
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 1995 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 
34 #include <floatingpoint.h>
35 
36 #ifdef DEBUG
37 #include <stdio.h>
38 #include <assert.h>
39 #endif
40 
41 /* Sun floating-point PRIVATE include file.  */
42 
43 /* PRIVATE MACROS	 */
44 
45 #ifdef DEBUG
46 #define PRIVATE
47 #else
48 #define PRIVATE static
49 #endif
50 
51 /* PRIVATE CONSTANTS	 */
52 
53 #define	SINGLE_BIAS	  127
54 #define DOUBLE_BIAS	 1023
55 #define EXTENDED_BIAS	16383
56 #define QUAD_BIAS	16383
57 
58 #define SINGLE_MAXE	  97	/* Maximum decimal exponent we need to
59 				 * consider. */
60 #define DOUBLE_MAXE	 771	/* Maximum decimal exponent we need to
61 				 * consider. */
62 #define EXTENDED_MAXE  12330	/* Maximum decimal exponent we need to
63 				 * consider. */
64 #define QUAD_MAXE  12330	/* Maximum decimal exponent we need to
65 				 * consider. */
66 
67 #define UNPACKED_SIZE	5	/* Size of unpacked significand.  */
68 
69 /* PRIVATE TYPES 	 */
70 
71 /*
72  * Unpack floating-point internal format.
73  * Value is 0.s0s1..sn * 2**(1+exponent)
74  */
75 typedef struct {
76 	int             sign;
77 	enum fp_class_type fpclass;
78 	int             exponent;	/* Unbiased exponent. */
79 	unsigned        significand[UNPACKED_SIZE];	/* Last word is round */
80 							/* and sticky. */
81 } unpacked;
82 
83 #ifdef i386
84 typedef struct {		/* Most significant word formats. */
85 	unsigned        significand:23;
86 	unsigned        exponent:8;
87 	unsigned        sign:1;
88 } single_msw;
89 
90 typedef struct {
91 	unsigned        significand:20;
92 	unsigned        exponent:11;
93 	unsigned        sign:1;
94 } double_msw;
95 
96 typedef struct {
97 	unsigned        exponent:15;
98 	unsigned        sign:1;
99 	unsigned        unused:16;
100 } extended_msw;
101 
102 typedef struct {
103 	unsigned        significand:16;
104 	unsigned        exponent:15;
105 	unsigned        sign:1;
106 } quadruple_msw;
107 
108 typedef struct {		/* Floating-point formats in detail. */
109 	single_msw      msw;
110 } single_formatted;
111 
112 typedef struct {
113 	unsigned        significand2;
114 	double_msw      msw;
115 } double_formatted;
116 
117 typedef struct {
118 	unsigned        significand2;
119 	unsigned        significand;
120 	extended_msw    msw;
121 } extended_formatted;
122 
123 typedef struct {
124 	unsigned        significand4;
125 	unsigned        significand3;
126 	unsigned        significand2;
127 	quadruple_msw   msw;
128 } quadruple_formatted;
129 #else
130 typedef struct {		/* Most significant word formats. */
131 	unsigned        sign:1;
132 	unsigned        exponent:8;
133 	unsigned        significand:23;
134 } single_msw;
135 
136 typedef struct {
137 	unsigned        sign:1;
138 	unsigned        exponent:11;
139 	unsigned        significand:20;
140 } double_msw;
141 
142 typedef struct {
143 	unsigned        sign:1;
144 	unsigned        exponent:15;
145 	unsigned        unused:16;
146 } extended_msw;
147 
148 typedef struct {
149 	unsigned        sign:1;
150 	unsigned        exponent:15;
151 	unsigned        significand:16;
152 } quadruple_msw;
153 
154 typedef struct {		/* Floating-point formats in detail. */
155 	single_msw      msw;
156 } single_formatted;
157 
158 typedef struct {
159 	double_msw      msw;
160 	unsigned        significand2;
161 } double_formatted;
162 
163 typedef struct {
164 	extended_msw    msw;
165 	unsigned        significand;
166 	unsigned        significand2;
167 } extended_formatted;
168 
169 typedef struct {
170 	quadruple_msw   msw;
171 	unsigned        significand2;
172 	unsigned        significand3;
173 	unsigned        significand4;
174 } quadruple_formatted;
175 #endif
176 
177 typedef union {			/* Floating-point formats equivalenced. */
178 	single_formatted f;
179 	single          x;
180 } single_equivalence;
181 
182 typedef union {
183 	double_formatted f;
184 	double          x;
185 } double_equivalence;
186 
187 typedef union {
188 	extended_formatted f;
189 	extended        x;
190 } extended_equivalence;
191 
192 typedef union {
193 	quadruple_formatted f;
194 	quadruple       x;
195 } quadruple_equivalence;
196 
197 /* PRIVATE GLOBAL VARIABLES */
198 
199 /* Current floating-point exceptions. */
200 fp_exception_field_type _fp_current_exceptions;
201 
202 /* Current rounding direction. */
203 enum fp_direction_type	_fp_current_direction;
204 
205 /* Current rounding precision. */
206 enum fp_precision_type	_fp_current_precision;
207 
208 /* PRIVATE FUNCTIONS */
209 
210 extern void _fp_set_exception(enum fp_exception_type);
211 /* enum fp_exception_type ex ; */	/* exception to be set in curexcep */
212 
213 /*
214  * Default size for _big_float - suitable for single and double precision.
215  */
216 
217 #define _BIG_FLOAT_SIZE	(DECIMAL_STRING_LENGTH/2)
218 #define _BIG_FLOAT_DIGIT short unsigned	/* big_float significand type */
219 
220 /* Maximum number of integer digits in a representable extended or quad. */
221 #define _INTEGER_SIZE	4932
222 
223 typedef struct {		/* Variable-precision floating-point type */
224 				/* used for intermediate results.	 */
225 	unsigned short  bsize;	/* Maximum allowable logical length of */
226 				/* significand. */
227 	unsigned short  blength;	/* Logical length of significand. */
228 	short int       bexponent;	/*
229 					 * Exponent to be attached to least
230 					 * significant word of significand.
231 					 * exponent >= 0 implies all integer,
232 					 * with decimal point to right of
233 					 * least significant word of
234 					 * significand, and is equivalent to
235 					 * number of omitted trailing zeros
236 					 * of significand. -length < exponent
237 					 * < 0  implies decimal point within
238 					 * significand. exponent = -length
239 					 * implies decimal point to left of
240 					 * most significand word. exponent <
241 					 * -length implies decimal point to
242 					 * left of most significant word with
243 					 * -length-exponent leading zeros.
244 					 */
245 	/*
246 	 * NOTE: bexponent represents a power of 2 or 10, even though big
247 	 * digits are powers of 2**16 or 10**4.
248 	 */
249 	_BIG_FLOAT_DIGIT bsignificand[_BIG_FLOAT_SIZE];
250 	/*
251 	 * Significand of digits in base 10**4 or 2**16. significand[0] is
252 	 * least significant, significand[length-1] is most significant.
253 	 */
254 } _big_float;
255 
256 #define BIG_FLOAT_TIMES_NOMEM	(_big_float *)0
257 #define BIG_FLOAT_TIMES_TOOBIG	(_big_float *)1
258 
259 /* Internal functions defined in base conversion support routines. */
260 
261 extern void     _multiply_base_ten(_big_float *, _BIG_FLOAT_DIGIT);
262 extern void     _multiply_base_ten_by_two(_big_float *, short unsigned);
263 extern void     _multiply_base_two(_big_float *, _BIG_FLOAT_DIGIT,
264     long unsigned);
265 extern void     _carry_propagate_two(unsigned long, _BIG_FLOAT_DIGIT *);
266 extern void     _carry_propagate_ten(unsigned long, _BIG_FLOAT_DIGIT *);
267 extern void     _multiply_base_two_vector(short unsigned, _BIG_FLOAT_DIGIT *,
268     short unsigned *, _BIG_FLOAT_DIGIT []);
269 extern void     _multiply_base_ten_vector(short unsigned, _BIG_FLOAT_DIGIT *,
270     short unsigned *, _BIG_FLOAT_DIGIT []);
271 extern void     _fourdigitsquick(short unsigned, char*);
272 extern void     _unpacked_to_big_float(unpacked *, _big_float *, int *);
273 extern void     _big_binary_to_big_decimal(_big_float *, _big_float *);
274 extern void     _left_shift_base_ten(_big_float *, short unsigned);
275 extern void     _left_shift_base_two(_big_float *, short unsigned);
276 extern void     _right_shift_base_two(_big_float *, short unsigned,
277     _BIG_FLOAT_DIGIT *);
278 extern void     _free_big_float(_big_float *);
279 extern void	_base_conversion_abort(int, char *);
280 extern void	_display_big_float(_big_float *, unsigned);
281 extern void	_integerstring_to_big_decimal(char [], unsigned, unsigned,
282     unsigned *, _big_float *);
283 extern void	_fractionstring_to_big_decimal(char [], unsigned, unsigned,
284     _big_float *);
285 extern void	_big_decimal_to_big_binary(_big_float *, _big_float *);
286 extern void	_fp_rightshift(unpacked *, int);
287 extern void	_fp_leftshift(unpacked *, unsigned);
288 extern void	_fp_normalize(unpacked *);
289 extern void	_pack_single(unpacked *, single *);
290 extern void	_pack_double(unpacked *, double *);
291 extern void	_pack_extended(unpacked *, extended *);
292 extern void	_pack_quadruple(unpacked *, quadruple *);
293 extern void	_unpack_single(unpacked *, single *);
294 extern void	_unpack_double(unpacked *, double *);
295 extern void	_unpack_extended(unpacked *, extended *);
296 extern void	_unpack_quadruple(unpacked *, quadruple *);
297 extern void	_unpacked_to_decimal(unpacked *, decimal_mode *,
298     decimal_record *, fp_exception_field_type *);
299 extern enum fp_class_type	_class_single(single *);
300 extern enum fp_class_type	_class_double(double *);
301 extern enum fp_class_type	_class_extended(extended *);
302 extern enum fp_class_type	_class_quadruple(quadruple *);
303 
304 /*
305  * Fundamental utilities that multiply or add two shorts into a unsigned long,
306  * sometimes add an unsigned long carry,
307  * compute quotient and remainder in underlying base, and return
308  * quo<<16 | rem as  a unsigned long.
309  */
310 
311 extern unsigned long _umac(_BIG_FLOAT_DIGIT, _BIG_FLOAT_DIGIT, unsigned long);
312 	/* p = x * y + c ; return p */
313 
314 #define _prodc_b65536(x,y,c) (_umac((x),(y),(c)))
315 
316 extern unsigned long _prodc_b10000(_BIG_FLOAT_DIGIT, _BIG_FLOAT_DIGIT,
317     unsigned long);
318 /* p = x * y + c ; return (p/10000 << */
319 
320 extern unsigned long _prod_b10000(_BIG_FLOAT_DIGIT, _BIG_FLOAT_DIGIT);
321 /* p = x * y ; return (p/10000 << 16 | p%10000) */
322 
323 extern unsigned long _prod_10000_b65536(_BIG_FLOAT_DIGIT, long unsigned);
324 /* p = x * 10000 + c ; return p */
325 
326 extern unsigned long _prod_65536_b10000(_BIG_FLOAT_DIGIT, long unsigned);
327 /* p = x * 65536 + c ; return (p/10000 << 16 | p%10000) */
328 
329 #define _rshift_b65536(x,n,c) ((((unsigned long) (x)) << (16-(n))) + ((c)<<16))
330 
331 #define _lshift_b65536(x,n,c) ((((unsigned long) (x)) << (n)) + (c))
332 
333 extern unsigned long _lshift_b10000(_BIG_FLOAT_DIGIT, _BIG_FLOAT_DIGIT,
334     long unsigned);
335 /* p = x << n + c ; return (p/10000 << 16 | p%10000) */
336 
337 #define _carry_in_b65536(x,c) ((x) + (c))
338 
339 extern unsigned long _carry_in_b10000(_BIG_FLOAT_DIGIT, long unsigned);
340 /* p = x + c ; return (p/10000 << 16 | p%10000) */
341 
342 #define _carry_out_b65536(c) (c)
343 
344 extern unsigned long _carry_out_b10000(unsigned long);
345 /* p = c ; return (p/10000 << 16 | p%10000) */
346 
347 /*
348  * Header file for revised "fast" base conversion based upon table look-up
349  * methods.
350  */
351 
352 extern void
353 _big_float_times_power(_big_float *, int, int, int, _big_float **);
354 
355 /* Variables defined in _small_powers.c and _big_powers.c	 */
356 /* Used in base conversion. */
357 
358 /*
359  * The run-time structure consists of two large tables of powers - either
360  * powers of 10**4 in base 2**16 or vice versa.
361  *
362  * Suppose it's powers of T in base B.  Then
363  *
364  * _tiny_powers_T       contains TTINY entries, T**0, T**1, ... T**TTINY-1 where
365  * T is 2 or 10, TTINY is 16 or 4 _small_powers_T      contains TSMALL
366  * entries, T**0, T**1, ... T**TSMALL-1 where T is 2**TTINY or 10**TTINY
367  * _big_powers_T        contains TBIG entries, T**0, T**1, ... T**TBIG-1
368  * where T is (2**TTINY)**TSMALL or (10**TTINY)**TSMALL
369  *
370  * so that any power of T from 0 to T**(TTINY*TSMALL*TBIG-1) can be represented
371  * as a product of just two table entries.  Since the powers vary greatly in
372  * size, the tables are condensed to exclude leading and trailing zeros.  The
373  * following tables
374  *
375  * _max_tiny_powers_T			contains one entry, TTINY
376  * _start_tiny_powers_T                 contains TTINY entries
377  * _leading_zeros_tiny_powers_T         contains TTINY entries
378  * _max_small_powers_T			contains one entry, TSMALL
379  * _start_small_powers_T                contains TSMALL entries
380  * _leading_zeros_small_powers_T        contains TSMALL entries
381  * _max_big_powers_T			contains one entry, TBIG
382  * _start_big_powers_T                  contains TBIG entries
383  * _leading_zeros_big_powers_T          contains TBIG entries
384  *
385  * The powers are maintained with x[start] less significant than x[start+1], so
386  *
387  * The powers are maintained with x[start] less significant than x[start+1], so
388  * that the interpretation of a _small_powers_T entry is that
389  *
390  * T**i = (B**leading_zeros[i]) * (x[start[i]] + x[start[i]+1] * B + ...
391  * x[start[i+1]-1] * B**(start[i+1]-start[i]) )
392  *
393  * where B = (2 or 10)**TTINY
394  *
395  * The powers are listed consecutively in the tables, with start index and
396  * leading zero information retained and printed out at the end.
397  *
398  */
399 
400 extern unsigned short _max_tiny_powers_ten;
401 extern unsigned short _tiny_powers_ten[];
402 extern unsigned short _start_tiny_powers_ten[];
403 extern unsigned short _leading_zeros_tiny_powers_ten[];
404 extern unsigned short _max_tiny_powers_two;
405 extern unsigned short _tiny_powers_two[];
406 extern unsigned short _start_tiny_powers_two[];
407 
408 extern unsigned short _max_small_powers_ten;
409 extern unsigned short _small_powers_ten[];
410 extern unsigned short _start_small_powers_ten[];
411 extern unsigned short _leading_zeros_small_powers_ten[];
412 extern unsigned short _max_small_powers_two;
413 extern unsigned short _small_powers_two[];
414 extern unsigned short _start_small_powers_two[];
415 
416 extern unsigned short _max_big_powers_ten;
417 extern unsigned short _big_powers_ten[];
418 extern unsigned short _start_big_powers_ten[];
419 extern unsigned short _leading_zeros_big_powers_ten[];
420 extern unsigned short _max_big_powers_two;
421 extern unsigned short _big_powers_two[];
422 extern unsigned short _start_big_powers_two[];
423 
424 #endif /* _base_conversion_h */
425