xref: /onnv-gate/usr/src/lib/libc/inc/base_conversion.h (revision 6812:febeba71273d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*6812Sraf  * Common Development and Distribution License (the "License").
6*6812Sraf  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211016Sraf 
220Sstevel@tonic-gate /*
23*6812Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
271016Sraf #ifndef	BASE_CONVERSION_H
281016Sraf #define	BASE_CONVERSION_H
291016Sraf 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <errno.h>
330Sstevel@tonic-gate #include <floatingpoint.h>
340Sstevel@tonic-gate #include <sys/isa_defs.h>
350Sstevel@tonic-gate 
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate  * Common constants, types, and declarations for floating point
380Sstevel@tonic-gate  * base conversion
390Sstevel@tonic-gate  */
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /* PRIVATE CONSTANTS	 */
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /* exponent bias */
440Sstevel@tonic-gate #define	SINGLE_BIAS	  127
450Sstevel@tonic-gate #define	DOUBLE_BIAS	 1023
460Sstevel@tonic-gate #define	EXTENDED_BIAS	16383
470Sstevel@tonic-gate #define	QUAD_BIAS	16383
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 
500Sstevel@tonic-gate /* PRIVATE TYPES */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate /*
530Sstevel@tonic-gate  * Unpacked binary floating point format.  The binary point lies
540Sstevel@tonic-gate  * to the right of the most significant bit in significand[0].
550Sstevel@tonic-gate  * The exponent is unbiased.  The significand array is long enough
560Sstevel@tonic-gate  * that the last word never contains any bits we need to keep,
570Sstevel@tonic-gate  * just rounding information.
580Sstevel@tonic-gate  */
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #define	UNPACKED_SIZE	5
610Sstevel@tonic-gate 
620Sstevel@tonic-gate typedef struct {
630Sstevel@tonic-gate 	int		sign;
640Sstevel@tonic-gate 	enum fp_class_type fpclass;
650Sstevel@tonic-gate 	int		exponent;
660Sstevel@tonic-gate 	unsigned	significand[UNPACKED_SIZE];
670Sstevel@tonic-gate } unpacked;
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  * Packed binary floating point formats.  The *_msw structure
710Sstevel@tonic-gate  * corresponds to the most significant word.
720Sstevel@tonic-gate  */
730Sstevel@tonic-gate 
740Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
750Sstevel@tonic-gate 
760Sstevel@tonic-gate typedef struct {
770Sstevel@tonic-gate 	unsigned	significand:23;
780Sstevel@tonic-gate 	unsigned	exponent:8;
790Sstevel@tonic-gate 	unsigned	sign:1;
800Sstevel@tonic-gate } single_msw;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate typedef struct {
830Sstevel@tonic-gate 	unsigned	significand:20;
840Sstevel@tonic-gate 	unsigned	exponent:11;
850Sstevel@tonic-gate 	unsigned	sign:1;
860Sstevel@tonic-gate } double_msw;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate typedef struct {
890Sstevel@tonic-gate 	unsigned	exponent:15;
900Sstevel@tonic-gate 	unsigned	sign:1;
910Sstevel@tonic-gate 	unsigned	unused:16;
920Sstevel@tonic-gate } extended_msw;
930Sstevel@tonic-gate 
940Sstevel@tonic-gate typedef struct {
950Sstevel@tonic-gate 	unsigned	significand:16;
960Sstevel@tonic-gate 	unsigned	exponent:15;
970Sstevel@tonic-gate 	unsigned	sign:1;
980Sstevel@tonic-gate } quadruple_msw;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate typedef struct {
1010Sstevel@tonic-gate 	single_msw	msw;
1020Sstevel@tonic-gate } single_formatted;
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate typedef struct {
1050Sstevel@tonic-gate 	unsigned	significand2;
1060Sstevel@tonic-gate 	double_msw	msw;
1070Sstevel@tonic-gate } double_formatted;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate typedef struct {
1100Sstevel@tonic-gate 	unsigned	significand2;
1110Sstevel@tonic-gate 	unsigned	significand;
1120Sstevel@tonic-gate 	extended_msw	msw;
1130Sstevel@tonic-gate } extended_formatted;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate typedef struct {
1160Sstevel@tonic-gate 	unsigned	significand4;
1170Sstevel@tonic-gate 	unsigned	significand3;
1180Sstevel@tonic-gate 	unsigned	significand2;
1190Sstevel@tonic-gate 	quadruple_msw	msw;
1200Sstevel@tonic-gate } quadruple_formatted;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate #else
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate typedef struct {
1250Sstevel@tonic-gate 	unsigned	sign:1;
1260Sstevel@tonic-gate 	unsigned	exponent:8;
1270Sstevel@tonic-gate 	unsigned	significand:23;
1280Sstevel@tonic-gate } single_msw;
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate typedef struct {
1310Sstevel@tonic-gate 	unsigned	sign:1;
1320Sstevel@tonic-gate 	unsigned	exponent:11;
1330Sstevel@tonic-gate 	unsigned	significand:20;
1340Sstevel@tonic-gate } double_msw;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate typedef struct {
1370Sstevel@tonic-gate 	unsigned	sign:1;
1380Sstevel@tonic-gate 	unsigned	exponent:15;
1390Sstevel@tonic-gate 	unsigned	unused:16;
1400Sstevel@tonic-gate } extended_msw;
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate typedef struct {
1430Sstevel@tonic-gate 	unsigned	sign:1;
1440Sstevel@tonic-gate 	unsigned	exponent:15;
1450Sstevel@tonic-gate 	unsigned	significand:16;
1460Sstevel@tonic-gate } quadruple_msw;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate typedef struct {
1490Sstevel@tonic-gate 	single_msw	msw;
1500Sstevel@tonic-gate } single_formatted;
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate typedef struct {
1530Sstevel@tonic-gate 	double_msw	msw;
1540Sstevel@tonic-gate 	unsigned	significand2;
1550Sstevel@tonic-gate } double_formatted;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate typedef struct {
1580Sstevel@tonic-gate 	extended_msw	msw;
1590Sstevel@tonic-gate 	unsigned	significand;
1600Sstevel@tonic-gate 	unsigned	significand2;
1610Sstevel@tonic-gate } extended_formatted;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate typedef struct {
1640Sstevel@tonic-gate 	quadruple_msw   msw;
1650Sstevel@tonic-gate 	unsigned	significand2;
1660Sstevel@tonic-gate 	unsigned	significand3;
1670Sstevel@tonic-gate 	unsigned	significand4;
1680Sstevel@tonic-gate } quadruple_formatted;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate #endif
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate typedef union {
1730Sstevel@tonic-gate 	single_formatted f;
1740Sstevel@tonic-gate 	single		x;
1750Sstevel@tonic-gate } single_equivalence;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate typedef union {
1780Sstevel@tonic-gate 	double_formatted f;
1790Sstevel@tonic-gate 	double		x;
1800Sstevel@tonic-gate } double_equivalence;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate typedef union {
1830Sstevel@tonic-gate 	extended_formatted f;
1840Sstevel@tonic-gate 	extended	x;
1850Sstevel@tonic-gate } extended_equivalence;
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate typedef union {
1880Sstevel@tonic-gate 	quadruple_formatted f;
1890Sstevel@tonic-gate 	quadruple	x;
1900Sstevel@tonic-gate } quadruple_equivalence;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate /*
1930Sstevel@tonic-gate  * Multiple precision floating point type.  This type is suitable
1940Sstevel@tonic-gate  * for representing positive floating point numbers of variable
1950Sstevel@tonic-gate  * precision in either binary or decimal.  The bsignificand array
1960Sstevel@tonic-gate  * holds the digits of a multi-word integer, stored least significant
1970Sstevel@tonic-gate  * digit first, in either radix 2^16 or 10^4.  blength is the
1980Sstevel@tonic-gate  * length of the significand array.  bexponent is a power of two
1990Sstevel@tonic-gate  * or ten, so that the value represented is
2000Sstevel@tonic-gate  *
2010Sstevel@tonic-gate  *   2^(bexponent) * sum (bsignificand[i] * 2^(i*16))
2020Sstevel@tonic-gate  *
2030Sstevel@tonic-gate  * if binary, or
2040Sstevel@tonic-gate  *
2050Sstevel@tonic-gate  *   10^(bexponent) * sum (bsignificand[i] * 10^(i*4))
2060Sstevel@tonic-gate  *
2070Sstevel@tonic-gate  * if decimal, where the sum runs from i = 0 to blength - 1.
2080Sstevel@tonic-gate  * (Whether the representation is binary or decimal is implied
2090Sstevel@tonic-gate  * from context.)  bsize indicates the size of the significand
2100Sstevel@tonic-gate  * array and may be larger than _BIG_FLOAT_SIZE if storage has
2110Sstevel@tonic-gate  * been allocated at runtime.
2120Sstevel@tonic-gate  */
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate #define	_BIG_FLOAT_SIZE	(DECIMAL_STRING_LENGTH/2)
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate typedef struct {
2170Sstevel@tonic-gate 	unsigned short  bsize;
2180Sstevel@tonic-gate 	unsigned short  blength;
2190Sstevel@tonic-gate 	short int	bexponent;
2200Sstevel@tonic-gate 	unsigned short	bsignificand[_BIG_FLOAT_SIZE];
2210Sstevel@tonic-gate } _big_float;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /* structure for storing IEEE modes and status flags */
2240Sstevel@tonic-gate typedef struct {
2250Sstevel@tonic-gate 	int	status, mode;
2260Sstevel@tonic-gate } __ieee_flags_type;
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /* PRIVATE GLOBAL VARIABLES */
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate /*
232*6812Sraf  * Thread-specific flags to indicate whether any NaNs or infinities
233*6812Sraf  * have been read or written.
2340Sstevel@tonic-gate  */
235*6812Sraf extern int *_thrp_get_inf_read(void);
236*6812Sraf extern int *_thrp_get_inf_written(void);
237*6812Sraf extern int *_thrp_get_nan_read(void);
238*6812Sraf extern int *_thrp_get_nan_written(void);
2390Sstevel@tonic-gate 
240*6812Sraf #define	__inf_read		(*(int *)_thrp_get_inf_read())
241*6812Sraf #define	__inf_written		(*(int *)_thrp_get_inf_written())
242*6812Sraf #define	__nan_read		(*(int *)_thrp_get_nan_read())
243*6812Sraf #define	__nan_written		(*(int *)_thrp_get_nan_written())
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate /*
2460Sstevel@tonic-gate  * Powers of 5 in base 2**16 and powers of 2 in base 10**4.
2470Sstevel@tonic-gate  *
2480Sstevel@tonic-gate  * __tbl_10_small_digits	contains
2490Sstevel@tonic-gate  *	5**0,
2500Sstevel@tonic-gate  *	5**1, ...
2510Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE-1
2520Sstevel@tonic-gate  * __tbl_10_big_digits		contains
2530Sstevel@tonic-gate  *	5**0,
2540Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE, ...
2550Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE*(__TBL_10_BIG_SIZE-1)
2560Sstevel@tonic-gate  * __tbl_10_huge_digits		contains
2570Sstevel@tonic-gate  *	5**0,
2580Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE, ...
2590Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*(__TBL_10_HUGE_SIZE-1)
2600Sstevel@tonic-gate  *
2610Sstevel@tonic-gate  * so that any power of 5 from 5**0 to
2620Sstevel@tonic-gate  *	5**__TBL_10_SMALL_SIZE*__TBL_10_BIG_SIZE*__TBL_10_HUGE_SIZE
2630Sstevel@tonic-gate  * can be represented as a product of at most three table entries.
2640Sstevel@tonic-gate  *
2650Sstevel@tonic-gate  * Similarly any power of 2 from 2**0 to
2660Sstevel@tonic-gate  *	2**__TBL_2_SMALL_SIZE*__TBL_2_BIG_SIZE*__TBL_2_HUGE_SIZE
2670Sstevel@tonic-gate  * can be represented as a product of at most three table entries.
2680Sstevel@tonic-gate  *
2690Sstevel@tonic-gate  * Since the powers vary greatly in size, the tables are condensed:
2700Sstevel@tonic-gate  * entry i in table x is stored in
2710Sstevel@tonic-gate  *	x_digits[x_start[i]] (least significant)
2720Sstevel@tonic-gate  * through
2730Sstevel@tonic-gate  *	x_digits[x_start[i+1]-1] (most significant)
2740Sstevel@tonic-gate  */
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate #define	__TBL_10_SMALL_SIZE	64
2770Sstevel@tonic-gate #define	__TBL_10_BIG_SIZE	16
2780Sstevel@tonic-gate #define	__TBL_10_HUGE_SIZE	6
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate extern const unsigned short
2810Sstevel@tonic-gate 	__tbl_10_small_digits[], __tbl_10_small_start[],
2820Sstevel@tonic-gate 	__tbl_10_big_digits[], __tbl_10_big_start[],
2830Sstevel@tonic-gate 	__tbl_10_huge_digits[], __tbl_10_huge_start[];
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate #define	__TBL_2_SMALL_SIZE	176
2860Sstevel@tonic-gate #define	__TBL_2_BIG_SIZE	16
2870Sstevel@tonic-gate #define	__TBL_2_HUGE_SIZE	6
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate extern const unsigned short
2900Sstevel@tonic-gate 	__tbl_2_small_digits[], __tbl_2_small_start[],
2910Sstevel@tonic-gate 	__tbl_2_big_digits[], __tbl_2_big_start[],
2920Sstevel@tonic-gate 	__tbl_2_huge_digits[], __tbl_2_huge_start[];
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate /*
2950Sstevel@tonic-gate  * Powers of ten.  For i = 0, 1, ..., __TBL_TENS_MAX, __tbl_tens[i]
2960Sstevel@tonic-gate  * = 10^i rounded to double precision.  (10^i is representable exactly
2970Sstevel@tonic-gate  * in double precision for i <= __TBL_TENS_EXACT.)
2980Sstevel@tonic-gate  */
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate #define	__TBL_TENS_EXACT	22
3010Sstevel@tonic-gate #define	__TBL_TENS_MAX		49
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate extern const double __tbl_tens[];
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate /* PRIVATE FUNCTIONS */
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate extern void __base_conversion_set_exception(fp_exception_field_type);
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate extern void __four_digits_quick(unsigned short, char *);
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate extern int __fast_double_to_decimal(double *dd, decimal_mode *pm,
3130Sstevel@tonic-gate 		decimal_record *pd, fp_exception_field_type *ps);
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate extern void __pack_single(unpacked *, single *, enum fp_direction_type,
3160Sstevel@tonic-gate 		fp_exception_field_type *);
3170Sstevel@tonic-gate extern void __pack_double(unpacked *, double *, enum fp_direction_type,
3180Sstevel@tonic-gate 		fp_exception_field_type *);
3190Sstevel@tonic-gate extern void __pack_extended(unpacked *, extended *, enum fp_direction_type,
3200Sstevel@tonic-gate 		fp_exception_field_type *);
3210Sstevel@tonic-gate extern void __pack_quadruple(unpacked *, quadruple *,
3220Sstevel@tonic-gate 		enum fp_direction_type, fp_exception_field_type *);
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate extern void __infnanstring(enum fp_class_type cl, int ndigits, char *buf);
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate extern void __big_float_times_power(_big_float *pbf, int mult, int n,
3270Sstevel@tonic-gate 		int precision, _big_float **pnewbf);
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate extern void __get_ieee_flags(__ieee_flags_type *);
3300Sstevel@tonic-gate extern void __set_ieee_flags(__ieee_flags_type *);
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate extern double __mul_set(double, double, int *);
3330Sstevel@tonic-gate extern double __div_set(double, double, int *);
3340Sstevel@tonic-gate extern double __dabs(double *);
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate #if defined(sparc) || defined(__sparc)
3370Sstevel@tonic-gate extern enum fp_direction_type _QgetRD(void);
3380Sstevel@tonic-gate #endif
3391016Sraf 
3401016Sraf #include "base_inlines.h"
3411016Sraf 
3421016Sraf #endif	/* BASE_CONVERSION_H */
343