xref: /illumos-gate/usr/src/head/floatingpoint.h (revision 8c16a0e6d0b3d6a8b804825076383c61979302ec)
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 /*	Copyright (C) 1989 AT&T	*/
22 /*	  All Rights Reserved */
23 
24 /*
25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
26  */
27 /*
28  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
29  * Use is subject to license terms.
30  */
31 
32 #ifndef _FLOATINGPOINT_H
33 #define	_FLOATINGPOINT_H
34 
35 #ifdef __STDC__
36 #include <stdio_tag.h>
37 #endif
38 #include <sys/ieeefp.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * <floatingpoint.h> contains definitions for constants, types, variables,
46  * and functions for:
47  *	IEEE floating-point arithmetic base conversion;
48  *	IEEE floating-point arithmetic modes;
49  *	IEEE floating-point arithmetic exception handling.
50  */
51 #if defined(__STDC__) && !defined(_FILEDEFED)
52 #define	_FILEDEFED
53 typedef	__FILE FILE;
54 #endif
55 
56 typedef int sigfpe_code_type;	/* Type of SIGFPE code. */
57 
58 typedef void (*sigfpe_handler_type)();	/* Pointer to exception handler */
59 
60 #define	SIGFPE_DEFAULT (void (*)())0	/* default exception handling */
61 #define	SIGFPE_IGNORE  (void (*)())1	/* ignore this exception or code */
62 #define	SIGFPE_ABORT   (void (*)())2	/* force abort on exception */
63 
64 extern sigfpe_handler_type sigfpe(sigfpe_code_type, sigfpe_handler_type);
65 
66 /*
67  * Types for IEEE floating point.
68  */
69 typedef float single;
70 
71 #ifndef _EXTENDED
72 #define	_EXTENDED
73 typedef unsigned extended[3];
74 #endif
75 
76 typedef long double quadruple;	/* Quadruple-precision type. */
77 
78 typedef unsigned fp_exception_field_type;
79 				/*
80 				 * A field containing fp_exceptions OR'ed
81 				 * together.
82 				 */
83 /*
84  * Definitions for base conversion.
85  */
86 #define	DECIMAL_STRING_LENGTH 512	/* Size of buffer in decimal_record. */
87 
88 typedef char decimal_string[DECIMAL_STRING_LENGTH];
89 				/* Decimal significand. */
90 
91 typedef struct {
92 	enum fp_class_type fpclass;
93 	int	sign;
94 	int	exponent;
95 	decimal_string ds;	/* Significand - each char contains an ascii */
96 				/* digit, except the string-terminating */
97 				/* ascii null. */
98 	int	more;		/* On conversion from decimal to binary, != 0 */
99 				/* indicates more non-zero digits following */
100 				/* ds. */
101 	int	ndigits;	/* On fixed_form conversion from binary to */
102 				/* decimal, contains number of digits */
103 				/* required for ds. */
104 } decimal_record;
105 
106 enum decimal_form {
107 	fixed_form,		/* Fortran F format: ndigits specifies number */
108 				/* of digits after point; if negative, */
109 				/* specifies rounding to occur to left of */
110 				/* point. */
111 	floating_form		/* Fortran E format: ndigits specifies number */
112 				/* of significant digits. */
113 };
114 
115 typedef struct {
116 	enum fp_direction_type rd;
117 				/* Rounding direction. */
118 	enum decimal_form df;	/* Format for conversion from binary to */
119 				/* decimal. */
120 	int ndigits;		/* Number of digits for conversion. */
121 } decimal_mode;
122 
123 enum decimal_string_form {	/* Valid decimal number string formats. */
124 	invalid_form,		/* Not a valid decimal string format. */
125 	whitespace_form,	/* All white space - valid in Fortran! */
126 	fixed_int_form,		/* <digs>		*/
127 	fixed_intdot_form,	/* <digs>.		*/
128 	fixed_dotfrac_form,	/* .<digs>		*/
129 	fixed_intdotfrac_form,	/* <digs>.<frac>	*/
130 	floating_int_form,	/* <digs><exp>		*/
131 	floating_intdot_form,	/* <digs>.<exp>		*/
132 	floating_dotfrac_form,	/* .<digs><exp>		*/
133 	floating_intdotfrac_form, /* <digs>.<digs><exp>	*/
134 	inf_form,		/* inf			*/
135 	infinity_form,		/* infinity		*/
136 	nan_form,		/* nan			*/
137 	nanstring_form		/* nan(string)		*/
138 };
139 
140 extern void single_to_decimal(single *, decimal_mode *, decimal_record *,
141     fp_exception_field_type *);
142 extern void double_to_decimal(double *, decimal_mode *, decimal_record *,
143     fp_exception_field_type *);
144 extern void extended_to_decimal(extended *, decimal_mode *,
145     decimal_record *, fp_exception_field_type *);
146 extern void quadruple_to_decimal(quadruple *, decimal_mode *,
147     decimal_record *, fp_exception_field_type *);
148 
149 extern void decimal_to_single(single *, decimal_mode *, decimal_record *,
150     fp_exception_field_type *);
151 extern void decimal_to_double(double *, decimal_mode *, decimal_record *,
152     fp_exception_field_type *);
153 extern void decimal_to_extended(extended *, decimal_mode *,
154     decimal_record *, fp_exception_field_type *);
155 extern void decimal_to_quadruple(quadruple *, decimal_mode *,
156     decimal_record *, fp_exception_field_type *);
157 
158 extern void string_to_decimal(char **, int, int, decimal_record *,
159     enum decimal_string_form *, char **);
160 extern void func_to_decimal(char **, int, int, decimal_record *,
161     enum decimal_string_form *, char **,
162     int (*)(void), int *, int (*)(int));
163 extern void file_to_decimal(char **, int, int, decimal_record *,
164     enum decimal_string_form *, char **,
165     FILE *, int *);
166 
167 extern char *seconvert(single *, int, int *, int *, char *);
168 extern char *sfconvert(single *, int, int *, int *, char *);
169 extern char *sgconvert(single *, int, int, char *);
170 extern char *econvert(double, int, int *, int *, char *);
171 extern char *fconvert(double, int, int *, int *, char *);
172 extern char *gconvert(double, int, int, char *);
173 extern char *qeconvert(quadruple *, int, int *, int *, char *);
174 extern char *qfconvert(quadruple *, int, int *, int *, char *);
175 extern char *qgconvert(quadruple *, int, int, char *);
176 
177 extern char *ecvt(double, int, int *, int *);
178 extern char *fcvt(double, int, int *, int *);
179 extern char *gcvt(double, int, char *);
180 
181 #if __cplusplus >= 199711L
182 namespace std {
183 #endif
184 /*
185  * ANSI C Standard says the following entry points should be
186  * prototyped in <stdlib.h>.  They are now, but weren't before.
187  */
188 extern double atof(const char *);
189 extern double strtod(const char *, char **);
190 #if __cplusplus >= 199711L
191 }
192 
193 using std::atof;
194 using std::strtod;
195 #endif /* end of namespace std */
196 
197 #ifdef __cplusplus
198 }
199 #endif
200 
201 #endif /* _FLOATINGPOINT_H */
202