SXEmacs, meet Dbus. Dbus, meet SXEmacs
[sxemacs] / src / ent / ent-inf.h
1 /*
2   ent-inf.h -- Infinite and Nan Predicates
3   Copyright (C) 2005, 2006 Sebastian Freundt
4   Copyright (C) 2006 Nelson Ferreira
5
6   Author:  Sebastian Freundt
7            Nelson Ferreira
8
9 This file is part of SXEmacs
10
11 SXEmacs is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 SXEmacs is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
23
24 #ifndef INCLUDED_ent_inf_h_
25 #define INCLUDED_ent_inf_h_
26
27 #if defined HAVE_MATH_H
28 # include <math.h>
29 #endif  /* HAVE_MATH_H */
30 #if defined HAVE_LIMITS_H
31 # include <limits.h>
32 #endif  /* HAVE_LIMITS_H */
33 #if defined HAVE_VALUES_H
34 # include <values.h>
35 #endif  /* HAVE_VALUES_H */
36
37 #if defined HAVE_STDBOOL_H
38 # include <stdbool.h>
39 #endif  /* HAVE_STDBOOL_H */
40
41 #if defined HAVE_IEEEFP_H
42 # include <ieeefp.h>
43 #endif /* HAVE_IEEEFP_H */
44
45 #if defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN
46 # define sxe_isnan      isnan
47 #else  /* !HAVE_ISNAN */
48 /* tenative work around */
49 # define sxe_isnan(x)   ((x) != (x))
50 # warning Your isnan() should be spelt isfscked().  Any ideas?
51 #endif  /* !HAVE_ISNAN */
52
53 #if defined HAVE_MATHS_ISINF || defined HAVE_ISINF
54 # define sxe_isinf      isinf
55 #elif defined HAVE_MATHS_FINITE || defined HAVE_FINITE
56 # define sxe_isinf(x)   (!finite(x))
57 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
58 # define sxe_isinf(x)   (fpclassify(x) == FP_INFINITE)
59 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
60 # define sxe_isinf(x)   (fpclass(x) == FP_PINF || fpclass(x) == FP_NINF)
61 #else /* anyone? */
62 # warning Your isinf() supply disgusts me.  How about grilling your box?
63 #endif  /* HAVE_ISINF */
64
65 #if defined HAVE_MATHS_SIGNBIT || defined HAVE_SIGNBIT
66 # define sxe_signbit    signbit
67 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
68 # define sxe_signbit(x) (fpclass(x) == FP_NINF || fpclass(x) == FP_NDENORM || fpclass(x) == FP_NZERO || fpclass(x) == FP_NNORM)
69 #else  /* !HAVE_SIGNBIT */
70 # define sxe_signbit(x) ((x) < 0)
71 # warning Your signbit() computation is vile.  Consider scrapping your machine.
72 #endif  /* HAVE_SIGNBIT */
73
74 #if 0
75 /* just to change the order more easily */
76
77 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
78 /* this one next, as gcc seems to have optimised built-ins for this */
79 # define ENT_FLOAT_INF_P(_val)  (isinf(_val))
80
81 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
82 # define ENT_FLOAT_INF_P(_val)  (fpclassify(_val) == FP_INFINITE)
83
84 #elif defined HAVE_MATHS_FINITE || defined HAVE_FINITE
85 /* this one next, as gcc seems to have optimised built-ins for this */
86 # define ENT_FLOAT_INF_P(_val)  (!finite(_val))
87
88 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
89 # define ENT_FLOAT_INF_P(_val)  (fpclass(_val) == FP_PINF || fpclass(_val) == FP_NINF)
90
91 #elif defined(HAVE_MATHS_INFINITY) && 0
92 /* very ugly as INFINITY is actually of type float */
93 # define ENT_FLOAT_INF_P(_val)  ((_val) == INFINITY || (_val) == -INFINITY)
94
95 #else
96 # define ENT_FLOAT_INF_P(_val)  (sxe_isinf(_val))
97 # warning infinity detection does not work
98 # warning assuming there are no infinities on your system
99 #endif
100
101 /* an inline variant to avoid multiple evaluation of X */
102 static inline bool __attribute__((always_inline))
103 ent_float_inf_p(fpfloat x)
104 {
105         return ENT_FLOAT_INF_P(x);
106 }
107
108 #if 0
109 /* just to change the order more easily */
110
111 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
112 /* isinf() returns +1 if _val is infinite and >= 0 */
113 # define ENT_FLOAT_PINF_P(_val) (isinf(_val) == 1)
114
115 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
116 /* this became second choice as there is an additional signbit evaluation */
117 # define ENT_FLOAT_PINF_P(_val)                                         \
118         (fpclassify(_val) == FP_INFINITE && sxe_signbit(_val) == 0)
119
120 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
121 # define ENT_FLOAT_PINF_P(_val) (fpclass(_val) == FP_PINF)
122
123 #elif defined(HAVE_MATHS_INFINITY) && 0
124 /* deprecated since types do not match */
125 # define ENT_FLOAT_PINF_P(_val) ((_val) == INFINITY)
126
127 #else
128 # define ENT_FLOAT_PINF_P(_val) (sxe_isinf(_val) && sxe_signbit(_val) == 0)
129 #endif
130
131 /* a recommended inline variant to avoid multiple evaluation of X */
132 static inline bool __attribute__((always_inline))
133 ent_float_pinf_p(fpfloat x)
134 {
135         return ENT_FLOAT_PINF_P(x);
136 }
137
138 #if 0
139 /* just so we can change the order easily */
140
141 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
142 /* isinf() is supposed to return -1 if _val is infinite and < 0 */
143 # define ENT_FLOAT_NINF_P(_val) (isinf(_val) == -1)
144
145 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
146 /* second choice, as isinf() seems to be more optimised */
147 # define ENT_FLOAT_NINF_P(_val)                                         \
148         (fpclassify(_val) == FP_INFINITE && sxe_signbit(_val) != 0)
149
150 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
151 # define ENT_FLOAT_NINF_P(_val) (fpclass(_val) == FP_NINF)
152
153 #elif defined(HAVE_MATHS_INFINITY) && 0
154 /* type mismatch hence deprecated */
155 # define ENT_FLOAT_NINF_P(_val) ((_val) == -INFINITY)
156
157 #else
158 # define ENT_FLOAT_NINF_P(_val) (sxe_isinf(_val) && sxe_signbit(_val) != 0)
159 #endif
160
161 /* a recommended inline variant to avoid multiple evaluation of X */
162 static inline bool __attribute__((always_inline))
163 ent_float_ninf_p(fpfloat x)
164 {
165         return ENT_FLOAT_NINF_P(x);
166 }
167
168 #if 0
169 /* just so we can change the order easily */
170
171 #elif defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN
172 /* preferred as gcc can optimise this one */
173 # define ENT_FLOAT_NAN_P(_val)  (isnan(_val))
174
175 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
176 # define ENT_FLOAT_NAN_P(_val)  (fpclassify(_val) == FP_NAN)
177
178 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
179 # define ENT_FLOAT_NAN_P(_val)  (fpclass(_val) == FP_QNAN || fpclass(_val) == FP_SNAN)
180
181 #elif defined(HAVE_MATHS_NAN) && 0
182 /* disabled because of a type mismatch */
183 # define ENT_FLOAT_NAN_P(_val)  ((_val) == NAN)
184
185 #else
186 # define ENT_FLOAT_NAN_P(_val)  (sxe_isnan(_val))
187 # warning NAN detection possibly broken
188 # warning Hate mails please to your system vendor.
189 #endif
190
191 /* an inline variant to avoid multiple evaluation of X */
192 static inline bool __attribute__((always_inline))
193 ent_float_nan_p(fpfloat x)
194 {
195         return ENT_FLOAT_NAN_P(x);
196 }
197
198 #if 0
199 /* to make it easy to change the order */
200
201 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
202 # define ENT_FLOAT_INDEFINITE_P(_val)   (fpclassify(_val) != FP_NORMAL)
203
204 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
205 # define ENT_FLOAT_INDEFINITE_P(_val)   (fpclass(_val) == FP_NINF || fpclass(_val) == FP_PINF || fpclass(_val) == FP_SNAN || fpclass(_val) == FP_SNAN)
206
207 #elif (defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN) &&       \
208         (defined HAVE_MATHS_ISINF || defined HAVE_ISINF || defined HAVE_MATHS_FINITE || defined HAVE_FINITE)
209 # define ENT_FLOAT_INDEFINITE_P(_val)   (isnan(_val) || isinf(_val))
210
211 #elif defined(HAVE_MATHS_NAN) && defined(HAVE_MATHS_INFINITY) && 0
212 /* severe type mismatch */
213 # define ENT_FLOAT_INDEFINITE_P(_val)   (((_val) == NAN)||((_val) == INFINITY))
214
215 #else
216 /* VERY expensive */
217 # define ENT_FLOAT_INDEFINITE_P(_val)                           \
218         (ENT_FLOAT_INF_P(_val) || ENT_FLOAT_NAN_P(_val))
219 # if ! ((defined(HAVE_MATHS_NAN) || defined(HAVE_MATHS_INFINITY)) &&    \
220        (defined(HAVE_ISNAN) || defined(HAVE_ISINF)))
221 #  warning Indefinites detection possibly broken
222 #  warning Hate mails please to your system vendor.
223 # endif
224 #endif
225
226 /* an inline variant to avoid multiple evaluation of X, recommended */
227 static inline bool __attribute__((always_inline))
228 ent_float_indefinite_p(fpfloat x)
229 {
230         return ENT_FLOAT_INDEFINITE_P(x);
231 }
232
233 #endif /* INCLUDED_ent_inf_h_ */