Merge remote-tracking branch 'origin/master' into for-steve
[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_STDBOOL_H
28 # include <stdbool.h>
29 #endif  /* HAVE_STDBOOL_H */
30
31 #if defined HAVE_IEEEFP_H
32 # include <ieeefp.h>
33 #endif /* HAVE_IEEEFP_H */
34
35 #if defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN
36 # define sxe_isnan      isnan
37 #else  /* !HAVE_ISNAN */
38 /* tenative work around */
39 # define sxe_isnan(x)   ((x) != (x))
40 # warning Your isnan() should be spelt isfscked().  Any ideas?
41 #endif  /* !HAVE_ISNAN */
42
43 #if defined HAVE_MATHS_ISINF || defined HAVE_ISINF
44 # define sxe_isinf      isinf
45 #elif defined HAVE_MATHS_FINITE || defined HAVE_FINITE
46 # define sxe_isinf(x)   (!finite(x))
47 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
48 # define sxe_isinf(x)   (fpclassify(x) == FP_INFINITE)
49 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
50 # define sxe_isinf(x)   (fpclass(x) == FP_PINF || fpclass(x) == FP_NINF)
51 #else /* anyone? */
52 # warning Your isinf() supply disgusts me.  How about grilling your box?
53 #endif  /* HAVE_ISINF */
54
55 #if defined HAVE_MATHS_SIGNBIT || defined HAVE_SIGNBIT
56 # define sxe_signbit    signbit
57 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
58 # define sxe_signbit(x) (fpclass(x) == FP_NINF || fpclass(x) == FP_NDENORM || fpclass(x) == FP_NZERO || fpclass(x) == FP_NNORM)
59 #else  /* !HAVE_SIGNBIT */
60 # define sxe_signbit(x) ((x) < 0)
61 # warning Your signbit() computation is vile.  Consider scrapping your machine.
62 #endif  /* HAVE_SIGNBIT */
63
64 #if 0
65 /* just to change the order more easily */
66
67 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
68 /* this one next, as gcc seems to have optimised built-ins for this */
69 # define ENT_FLOAT_INF_P(_val)  (isinf(_val))
70
71 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
72 # define ENT_FLOAT_INF_P(_val)  (fpclassify(_val) == FP_INFINITE)
73
74 #elif defined HAVE_MATHS_FINITE || defined HAVE_FINITE
75 /* this one next, as gcc seems to have optimised built-ins for this */
76 # define ENT_FLOAT_INF_P(_val)  (!finite(_val))
77
78 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
79 # define ENT_FLOAT_INF_P(_val)  (fpclass(_val) == FP_PINF || fpclass(_val) == FP_NINF)
80
81 #elif defined(HAVE_MATHS_INFINITY) && 0
82 /* very ugly as INFINITY is actually of type float */
83 # define ENT_FLOAT_INF_P(_val)  ((_val) == INFINITY || (_val) == -INFINITY)
84
85 #else
86 # define ENT_FLOAT_INF_P(_val)  (sxe_isinf(_val))
87 # warning infinity detection does not work
88 # warning assuming there are no infinities on your system
89 #endif
90
91 /* an inline variant to avoid multiple evaluation of X */
92 static inline bool __attribute__((always_inline))
93 ent_float_inf_p(fpfloat x)
94 {
95         return ENT_FLOAT_INF_P(x);
96 }
97
98 #if 0
99 /* just to change the order more easily */
100
101 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
102 /* isinf() returns +1 if _val is infinite and >= 0 */
103 # define ENT_FLOAT_PINF_P(_val) (isinf(_val) == 1)
104
105 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
106 /* this became second choice as there is an additional signbit evaluation */
107 # define ENT_FLOAT_PINF_P(_val)                                         \
108         (fpclassify(_val) == FP_INFINITE && sxe_signbit(_val) == 0)
109
110 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
111 # define ENT_FLOAT_PINF_P(_val) (fpclass(_val) == FP_PINF)
112
113 #elif defined(HAVE_MATHS_INFINITY) && 0
114 /* deprecated since types do not match */
115 # define ENT_FLOAT_PINF_P(_val) ((_val) == INFINITY)
116
117 #else
118 # define ENT_FLOAT_PINF_P(_val) (sxe_isinf(_val) && sxe_signbit(_val) == 0)
119 #endif
120
121 /* a recommended inline variant to avoid multiple evaluation of X */
122 static inline bool __attribute__((always_inline))
123 ent_float_pinf_p(fpfloat x)
124 {
125         return ENT_FLOAT_PINF_P(x);
126 }
127
128 #if 0
129 /* just so we can change the order easily */
130
131 #elif defined HAVE_MATHS_ISINF || defined HAVE_ISINF
132 /* isinf() is supposed to return -1 if _val is infinite and < 0 */
133 # define ENT_FLOAT_NINF_P(_val) (isinf(_val) == -1)
134
135 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
136 /* second choice, as isinf() seems to be more optimised */
137 # define ENT_FLOAT_NINF_P(_val)                                         \
138         (fpclassify(_val) == FP_INFINITE && sxe_signbit(_val) != 0)
139
140 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
141 # define ENT_FLOAT_NINF_P(_val) (fpclass(_val) == FP_NINF)
142
143 #elif defined(HAVE_MATHS_INFINITY) && 0
144 /* type mismatch hence deprecated */
145 # define ENT_FLOAT_NINF_P(_val) ((_val) == -INFINITY)
146
147 #else
148 # define ENT_FLOAT_NINF_P(_val) (sxe_isinf(_val) && sxe_signbit(_val) != 0)
149 #endif
150
151 /* a recommended inline variant to avoid multiple evaluation of X */
152 static inline bool __attribute__((always_inline))
153 ent_float_ninf_p(fpfloat x)
154 {
155         return ENT_FLOAT_NINF_P(x);
156 }
157
158 #if 0
159 /* just so we can change the order easily */
160
161 #elif defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN
162 /* preferred as gcc can optimise this one */
163 # define ENT_FLOAT_NAN_P(_val)  (isnan(_val))
164
165 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
166 # define ENT_FLOAT_NAN_P(_val)  (fpclassify(_val) == FP_NAN)
167
168 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
169 # define ENT_FLOAT_NAN_P(_val)  (fpclass(_val) == FP_QNAN || fpclass(_val) == FP_SNAN)
170
171 #elif defined(HAVE_MATHS_NAN) && 0
172 /* disabled because of a type mismatch */
173 # define ENT_FLOAT_NAN_P(_val)  ((_val) == NAN)
174
175 #else
176 # define ENT_FLOAT_NAN_P(_val)  (sxe_isnan(_val))
177 # warning NAN detection possibly broken
178 # warning Hate mails please to your system vendor.
179 #endif
180
181 /* an inline variant to avoid multiple evaluation of X */
182 static inline bool __attribute__((always_inline))
183 ent_float_nan_p(fpfloat x)
184 {
185         return ENT_FLOAT_NAN_P(x);
186 }
187
188 #if 0
189 /* to make it easy to change the order */
190
191 #elif defined HAVE_MATHS_FPCLASSIFY || defined HAVE_FPCLASSIFY
192 # define ENT_FLOAT_INDEFINITE_P(_val)   (fpclassify(_val) != FP_NORMAL)
193
194 #elif defined HAVE_MATHS_FPCLASS || defined HAVE_FPCLASS
195 # define ENT_FLOAT_INDEFINITE_P(_val)   (fpclass(_val) == FP_NINF || fpclass(_val) == FP_PINF || fpclass(_val) == FP_SNAN || fpclass(_val) == FP_SNAN)
196
197 #elif (defined HAVE_MATHS_ISNAN || defined HAVE_ISNAN) &&       \
198         (defined HAVE_MATHS_ISINF || defined HAVE_ISINF || defined HAVE_MATHS_FINITE || defined HAVE_FINITE)
199 # define ENT_FLOAT_INDEFINITE_P(_val)   (isnan(_val) || isinf(_val))
200
201 #elif defined(HAVE_MATHS_NAN) && defined(HAVE_MATHS_INFINITY) && 0
202 /* severe type mismatch */
203 # define ENT_FLOAT_INDEFINITE_P(_val)   (((_val) == NAN)||((_val) == INFINITY))
204
205 #else
206 /* VERY expensive */
207 # define ENT_FLOAT_INDEFINITE_P(_val)                           \
208         (ENT_FLOAT_INF_P(_val) || ENT_FLOAT_NAN_P(_val))
209 # if ! ((defined(HAVE_MATHS_NAN) || defined(HAVE_MATHS_INFINITY)) &&    \
210        (defined(HAVE_ISNAN) || defined(HAVE_ISINF)))
211 #  warning Indefinites detection possibly broken
212 #  warning Hate mails please to your system vendor.
213 # endif
214 #endif
215
216 /* an inline variant to avoid multiple evaluation of X, recommended */
217 static inline bool __attribute__((always_inline))
218 ent_float_indefinite_p(fpfloat x)
219 {
220         return ENT_FLOAT_INDEFINITE_P(x);
221 }
222
223 #endif /* INCLUDED_ent_inf_h_ */