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
41extern "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
53typedef	__FILE FILE;
54#endif
55
56typedef int sigfpe_code_type;	/* Type of SIGFPE code. */
57
58typedef 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
64extern sigfpe_handler_type sigfpe(sigfpe_code_type, sigfpe_handler_type);
65
66/*
67 * Types for IEEE floating point.
68 */
69typedef float single;
70
71#ifndef _EXTENDED
72#define	_EXTENDED
73typedef unsigned extended[3];
74#endif
75
76typedef long double quadruple;	/* Quadruple-precision type. */
77
78typedef 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
88typedef char decimal_string[DECIMAL_STRING_LENGTH];
89				/* Decimal significand. */
90
91typedef 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
106enum 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
115typedef 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
123enum 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
140extern void single_to_decimal(single *, decimal_mode *, decimal_record *,
141    fp_exception_field_type *);
142extern void double_to_decimal(double *, decimal_mode *, decimal_record *,
143    fp_exception_field_type *);
144extern void extended_to_decimal(extended *, decimal_mode *,
145    decimal_record *, fp_exception_field_type *);
146extern void quadruple_to_decimal(quadruple *, decimal_mode *,
147    decimal_record *, fp_exception_field_type *);
148
149extern void decimal_to_single(single *, decimal_mode *, decimal_record *,
150    fp_exception_field_type *);
151extern void decimal_to_double(double *, decimal_mode *, decimal_record *,
152    fp_exception_field_type *);
153extern void decimal_to_extended(extended *, decimal_mode *,
154    decimal_record *, fp_exception_field_type *);
155extern void decimal_to_quadruple(quadruple *, decimal_mode *,
156    decimal_record *, fp_exception_field_type *);
157
158extern void string_to_decimal(char **, int, int, decimal_record *,
159    enum decimal_string_form *, char **);
160extern void func_to_decimal(char **, int, int, decimal_record *,
161    enum decimal_string_form *, char **,
162    int (*)(void), int *, int (*)(int));
163extern void file_to_decimal(char **, int, int, decimal_record *,
164    enum decimal_string_form *, char **,
165    FILE *, int *);
166
167extern char *seconvert(single *, int, int *, int *, char *);
168extern char *sfconvert(single *, int, int *, int *, char *);
169extern char *sgconvert(single *, int, int, char *);
170extern char *econvert(double, int, int *, int *, char *);
171extern char *fconvert(double, int, int *, int *, char *);
172extern char *gconvert(double, int, int, char *);
173extern char *qeconvert(quadruple *, int, int *, int *, char *);
174extern char *qfconvert(quadruple *, int, int *, int *, char *);
175extern char *qgconvert(quadruple *, int, int, char *);
176
177extern char *ecvt(double, int, int *, int *);
178extern char *fcvt(double, int, int *, int *);
179extern char *gcvt(double, int, char *);
180
181#if __cplusplus >= 199711L
182namespace 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 */
188extern double atof(const char *);
189extern double strtod(const char *, char **);
190#if __cplusplus >= 199711L
191}
192
193using std::atof;
194using std::strtod;
195#endif /* end of namespace std */
196
197#ifdef __cplusplus
198}
199#endif
200
201#endif /* _FLOATINGPOINT_H */
202