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 */