Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
FLOAT.cpp
Go to the documentation of this file.
1// computing floating point properties
2
3
25// working around a Compaq C++ headers problem (PR #27459)
26#if defined (__PURE_CNAME)
27# undef __PURE_CNAME
28#endif // __PURE_CNAME
29
30#include "config.h"
31
32enum {
33 // the enumerators below are expected to be hidden by macros #defined
34 // in the <float.h> header #included below through "float_defs.h";
35 // references to macros that are not #defined in the header will
36 // silently use these enumerators and prevent compilation errors that
37 // would result otherwise
38 DBL_DIG = 15, // default
43 DBL_MIN_EXP = -1021,
44
52
58 LDBL_MIN_EXP = -1
59};
60
61
62#include <errno.h> // for ERANGE, errno
63#include <stdio.h> // for printf()
64#include <stdlib.h> // for strtod()
65
66#include "float_defs.h" // for FLT_XXX, DBL_XXX, LDBL_XXX constants
67
68#ifndef _RWSTD_NO_LIBC_EXCEPTION_SPEC
69# define LIBC_THROWS() throw ()
70#else
71# define LIBC_THROWS() /* empty */
72#endif // _RWSTD_NO_LIBC_EXCEPTION_SPEC
73
74
75extern "C" {
76
77#ifdef _RWSTD_NO_STRTOF
78# ifndef _RWSTD_NO_STRTOF_IN_LIBC
79
80# undef _RWSTD_NO_STRTOF
81
82float strtof (const char*, char**) LIBC_THROWS ();
83
84# endif // _RWSTD_NO_STRTOF_IN_LIBC
85#endif // _RWSTD_NO_STRTOF
86
87#ifdef _RWSTD_NO_STRTOD
88# ifndef _RWSTD_NO_STRTOD_IN_LIBC
89
90# undef _RWSTD_NO_STRTOD
91
92double strtod (const char*, char**) LIBC_THROWS ();
93
94# endif // _RWSTD_NO_STRTOD_IN_LIBC
95#endif // _RWSTD_NO_STRTOD
96
97#ifndef _RWSTD_NO_LONG_DOUBLE
98# ifdef _RWSTD_NO_STRTOLD
99# ifndef _RWSTD_NO_STRTOLD_IN_LIBC
100
101# undef _RWSTD_NO_STRTOLD
102
103long double strtold (const char*, char**) LIBC_THROWS ();
104
105# endif // _RWSTD_NO_STRTOLD_IN_LIBC
106# endif // _RWSTD_NO_STRTOLD
107#endif // _RWSTD_NO_LONG_DOUBLE
108
109}
110
111
112#ifndef _RWSTD_NO_HONOR_STD
113# ifdef _RWSTD_NO_STD_TERMINATE
114# include "terminate.h"
115# endif // _RWSTD_NO_STD_TERMINATE
116#endif // _RWSTD_NO_HONOR_STD
117
118
119// print a floating point number, either as a string (if the stringized
120// constant is a valid number, and not some complex expression), or as
121// a formatted floating point value
122template <class FloatT>
123void print_float (FloatT x, const char *xstr,
124 const char *macro_name, const char *fmt, int prec)
125{
126 if ('-' == *xstr || '0' <= *xstr && '9' >= *xstr) {
127 printf ("#define _RWSTD_%-16s %s", macro_name, xstr);
128 }
129 else {
130 printf ("#define _RWSTD_%-16s ", macro_name);
131 printf (fmt, prec + 2, x);
132 }
133 puts ("");
134}
135
136#define DO_STRINGIZE(x) #x
137#define STRINGIZE(x) DO_STRINGIZE (x)
138
139#define PRINTINT(macro) \
140 if (-1 == (macro)) \
141 printf ("%s", "//"); \
142 printf ("#define _RWSTD_%-16s %6d\n", #macro, (macro))
143
144#define PRINTFLT(macro, fmt, prec, suffix) \
145 print_float (macro, STRINGIZE (macro), #macro, "%.*" fmt "e" suffix, prec)
146
147
148int main ()
149{
151 // compute floating point limits
152
153#undef LDBL_FMT
154
155#ifdef _RWSTD_LDBL_PRINTF_PREFIX
156# define LDBL_FMT _RWSTD_LDBL_PRINTF_PREFIX
157#else
158# define LDBL_FMT "L"
159#endif
160
161#if defined (FLT_ROUNDS)
162 printf ("#define _RWSTD_%-16s %6d /* %s */\n",
163 "FLT_ROUNDS", FLT_ROUNDS,
164 0 == FLT_ROUNDS ? "round toward zero"
165 : 1 == FLT_ROUNDS ? "round to nearest"
166 : 2 == FLT_ROUNDS ? "round toward infinity"
167 : 3 == FLT_ROUNDS ? "round toward negative infinity"
168 : "indeterminable");
169#endif // FLT_ROUNDS
170
177
185
186#ifndef _RWSTD_NO_LONG_DOUBLE
187
194
195#endif // _RWSTD_NO_LONG_DOUBLE
196
197
198#if defined (DBL_MAX)
199 PRINTFLT (DBL_MAX, "l", DBL_DIG, "");
200#endif // DBL_MAX
201
202#if defined (FLT_MAX)
203 PRINTFLT (FLT_MAX, "", FLT_DIG, "F");
204#endif // FLT_MAX
205
206#ifndef _RWSTD_NO_LONG_DOUBLE
207# if defined (LDBL_MAX)
209# endif // LDBL_MAX
210#endif // _RWSTD_NO_LONG_DOUBLE
211
212#if defined (DBL_EPSILON)
213 PRINTFLT (DBL_EPSILON, "l", DBL_DIG, "");
214#endif // DBL_EPSILON
215
216#if defined (DBL_MIN)
217 PRINTFLT (DBL_MIN, "l", DBL_DIG, "");
218#endif // DBL_MIN
219
220#if defined (FLT_EPSILON)
221 PRINTFLT (FLT_EPSILON, "", FLT_DIG, "F");
222#endif // FLT_EPSILON
223
224#if defined (FLT_MIN)
225 PRINTFLT (FLT_MIN, "", FLT_DIG, "F");
226#endif // FLT_MIN
227
228#ifndef _RWSTD_NO_LONG_DOUBLE
229# if defined (LDBL_EPSILON)
231# endif // LDBL_EPSILON
232
233# if defined (LDBL_MIN)
235# endif // LDBL_MIN
236#endif // _RWSTD_NO_LONG_DOUBLE
237
238
239#if !defined (ERANGE)
240# define ERANGE -1
241#endif // ERANGE
242
243#ifndef _RWSTD_NO_STRTOF
244
245 errno = 0;
246
247 // determine whether strtof() sets errno on underflow
248 const float f = strtof ("1.0e-999", (char**)0);
249
250
251 if (f < 0.0 || f > 1.0 || !errno)
252 printf ("#define _RWSTD_NO_STRTOF_UFLOW\n");
253 else
254 printf ("// #define _RWSTD_NO_STRTOF_UFLOW // %d%s\n",
255 errno, ERANGE == errno ? " (ERANGE)" : "");
256
257#endif // _RWSTD_NO_STRTOF
258
259#ifndef _RWSTD_NO_STRTOD
260
261 errno = 0;
262
263 // determine whether strtod() sets errno on underflow
264 const double d = strtod ("1.0e-999", (char**)0);
265
266
267 if (d < 0.0 || d > 1.0 || !errno)
268 printf ("#define _RWSTD_NO_STRTOD_UFLOW\n");
269 else
270 printf ("// #define _RWSTD_NO_STRTOD_UFLOW // %d%s\n",
271 errno, ERANGE == errno ? " (ERANGE)" : "");
272
273#endif // _RWSTD_NO_STRTOD
274
275#ifndef _RWSTD_NO_LONG_DOUBLE
276# ifndef _RWSTD_NO_STRTOLD
277
278 errno = 0;
279
280# if !defined (__hpux) || !defined (_LONG_DOUBLE)
281
282 // HP-UX strtold() returns struct long_double
283 // the macro _LONG_DOUBLE is #defined when the struct is defined
284 // note that gcc's replacement <stdlib.h> may actually define the
285 // function with the correct signature
286
287 // determine whether strtold() sets errno on underflow
288 const long double ld = strtold ("1.0e-9999", (char**)0);
289
290# else // HP-UX with _LONG_DOUBLE #defined
291
292 union {
293 long double ld;
294 long_double data;
295 } ldu;
296
297 ldu.data = strtold ("1.0e-9999", (char**)0);
298 const long double ld = ldu.ld;
299
300# endif // HP-UX, _LONG_DOUBLE
301
302 if (ld < 0.0 || ld > 1.0 || !errno)
303 printf ("#define _RWSTD_NO_STRTOLD_UFLOW\n");
304 else
305 printf ("// #define _RWSTD_NO_STRTOLD_UFLOW // %d%s\n",
306 errno, ERANGE == errno ? " (ERANGE)" : "");
307
308# endif // _RWSTD_NO_STRTOLD
309#endif // _RWSTD_NO_LONG_DOUBLE
310
311 return 0;
312}
313
314
#define d
Definition 17.names.cpp:115
#define x
Definition 17.names.cpp:140
#define f
Definition 17.names.cpp:119
const char *const data[]
IMPORT_C SInt32 printf(const Char *,...)
#define LIBC_THROWS()
Definition FLOAT.cpp:69
void print_float(FloatT x, const char *xstr, const char *macro_name, const char *fmt, int prec)
Definition FLOAT.cpp:123
#define ERANGE
@ DBL_DIG
Definition FLOAT.cpp:38
@ LDBL_DIG
Definition FLOAT.cpp:53
@ LDBL_MIN_10_EXP
Definition FLOAT.cpp:57
@ DBL_MANT_DIG
Definition FLOAT.cpp:39
@ FLT_MAX_EXP
Definition FLOAT.cpp:48
@ DBL_MAX_EXP
Definition FLOAT.cpp:41
@ DBL_MAX_10_EXP
Definition FLOAT.cpp:40
@ LDBL_MAX_EXP
Definition FLOAT.cpp:56
@ FLT_RADIX
Definition FLOAT.cpp:51
@ LDBL_MANT_DIG
Definition FLOAT.cpp:54
@ DBL_MIN_10_EXP
Definition FLOAT.cpp:42
@ LDBL_MAX_10_EXP
Definition FLOAT.cpp:55
@ DBL_MIN_EXP
Definition FLOAT.cpp:43
@ LDBL_MIN_EXP
Definition FLOAT.cpp:58
@ FLT_DIG
Definition FLOAT.cpp:45
@ FLT_MAX_10_EXP
Definition FLOAT.cpp:47
@ FLT_MIN_EXP
Definition FLOAT.cpp:50
@ FLT_MIN_10_EXP
Definition FLOAT.cpp:49
@ FLT_MANT_DIG
Definition FLOAT.cpp:46
#define PRINTFLT(macro, fmt, prec, suffix)
Definition FLOAT.cpp:144
#define PRINTINT(macro)
Definition FLOAT.cpp:139
#define LDBL_FMT
int main()
Definition FLOAT.cpp:148
#define LDBL_MIN
Definition _cfloat.h:67
#define FLT_ROUNDS
Definition _cfloat.h:37
#define FLT_MAX
Definition _cfloat.h:46
#define FLT_MIN
Definition _cfloat.h:47
#define FLT_EPSILON
Definition _cfloat.h:48
#define DBL_MIN
Definition _cfloat.h:57
#define DBL_EPSILON
Definition _cfloat.h:58
#define LDBL_EPSILON
Definition _cfloat.h:68
#define LDBL_MAX
Definition _cfloat.h:66
#define DBL_MAX
Definition _cfloat.h:56