Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5771dae

Browse files
committed
MAINT: move npy_(get,clear)_floatstatus() to their own file.
1 parent 2348023 commit 5771dae

3 files changed

Lines changed: 259 additions & 256 deletions

File tree

numpy/core/setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,8 @@ def get_mathlib_info(*args):
712712
npymath_sources = [join('src', 'npymath', 'npy_math.c.src'),
713713
join('src', 'npymath', 'ieee754.c.src'),
714714
join('src', 'npymath', 'npy_math_complex.c.src'),
715-
join('src', 'npymath', 'halffloat.c')]
715+
join('src', 'npymath', 'halffloat.c'),
716+
join('src', 'npymath', 'fpstatus.c')]
716717
config.add_installed_library('npymath',
717718
sources=npymath_sources + [get_mathlib_info],
718719
install_dir='lib')

numpy/core/src/npymath/fpstatus.c

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* Functions to set the floating point status word.
3+
* keep in sync with NO_FLOATING_POINT_SUPPORT in ufuncobject.h
4+
*/
5+
6+
#include "npy_math_common.h"
7+
8+
#if (defined(__unix__) || defined(unix)) && !defined(USG)
9+
#include <sys/param.h>
10+
#endif
11+
12+
/* Solaris --------------------------------------------------------*/
13+
/* --------ignoring SunOS ieee_flags approach, someone else can
14+
** deal with that! */
15+
#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
16+
(defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
17+
defined(__NetBSD__)
18+
#include <ieeefp.h>
19+
20+
int npy_get_floatstatus(void)
21+
{
22+
int fpstatus = fpgetsticky();
23+
return ((FP_X_DZ & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
24+
((FP_X_OFL & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
25+
((FP_X_UFL & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
26+
((FP_X_INV & fpstatus) ? NPY_FPE_INVALID : 0);
27+
}
28+
29+
int npy_clear_floatstatus(void)
30+
{
31+
int fpstatus = npy_get_floatstatus();
32+
fpsetsticky(0);
33+
34+
return fpstatus;
35+
}
36+
37+
void npy_set_floatstatus_divbyzero(void)
38+
{
39+
fpsetsticky(FP_X_DZ);
40+
}
41+
42+
void npy_set_floatstatus_overflow(void)
43+
{
44+
fpsetsticky(FP_X_OFL);
45+
}
46+
47+
void npy_set_floatstatus_underflow(void)
48+
{
49+
fpsetsticky(FP_X_UFL);
50+
}
51+
52+
void npy_set_floatstatus_invalid(void)
53+
{
54+
fpsetsticky(FP_X_INV);
55+
}
56+
57+
58+
#elif defined(__GLIBC__) || defined(__APPLE__) || \
59+
defined(__CYGWIN__) || defined(__MINGW32__) || \
60+
(defined(__FreeBSD__) && (__FreeBSD_version >= 502114))
61+
62+
# if defined(__GLIBC__) || defined(__APPLE__) || \
63+
defined(__MINGW32__) || defined(__FreeBSD__)
64+
# include <fenv.h>
65+
# elif defined(__CYGWIN__)
66+
# include "numpy/fenv/fenv.h"
67+
# endif
68+
69+
int npy_get_floatstatus(void)
70+
{
71+
int fpstatus = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW |
72+
FE_UNDERFLOW | FE_INVALID);
73+
74+
return ((FE_DIVBYZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
75+
((FE_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
76+
((FE_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
77+
((FE_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
78+
}
79+
80+
int npy_clear_floatstatus(void)
81+
{
82+
/* testing float status is 50-100 times faster than clearing on x86 */
83+
int fpstatus = npy_get_floatstatus();
84+
if (fpstatus != 0) {
85+
feclearexcept(FE_DIVBYZERO | FE_OVERFLOW |
86+
FE_UNDERFLOW | FE_INVALID);
87+
}
88+
89+
return fpstatus;
90+
}
91+
92+
93+
void npy_set_floatstatus_divbyzero(void)
94+
{
95+
feraiseexcept(FE_DIVBYZERO);
96+
}
97+
98+
void npy_set_floatstatus_overflow(void)
99+
{
100+
feraiseexcept(FE_OVERFLOW);
101+
}
102+
103+
void npy_set_floatstatus_underflow(void)
104+
{
105+
feraiseexcept(FE_UNDERFLOW);
106+
}
107+
108+
void npy_set_floatstatus_invalid(void)
109+
{
110+
feraiseexcept(FE_INVALID);
111+
}
112+
113+
#elif defined(_AIX)
114+
#include <float.h>
115+
#include <fpxcp.h>
116+
117+
int npy_get_floatstatus(void)
118+
{
119+
int fpstatus = fp_read_flag();
120+
return ((FP_DIV_BY_ZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
121+
((FP_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
122+
((FP_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
123+
((FP_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
124+
}
125+
126+
int npy_clear_floatstatus(void)
127+
{
128+
int fpstatus = npy_get_floatstatus();
129+
fp_swap_flag(0);
130+
131+
return fpstatus;
132+
}
133+
134+
void npy_set_floatstatus_divbyzero(void)
135+
{
136+
fp_raise_xcp(FP_DIV_BY_ZERO);
137+
}
138+
139+
void npy_set_floatstatus_overflow(void)
140+
{
141+
fp_raise_xcp(FP_OVERFLOW);
142+
}
143+
144+
void npy_set_floatstatus_underflow(void)
145+
{
146+
fp_raise_xcp(FP_UNDERFLOW);
147+
}
148+
149+
void npy_set_floatstatus_invalid(void)
150+
{
151+
fp_raise_xcp(FP_INVALID);
152+
}
153+
154+
#else
155+
156+
/* MS Windows -----------------------------------------------------*/
157+
#if defined(_MSC_VER)
158+
159+
#include <float.h>
160+
161+
162+
int npy_get_floatstatus(void)
163+
{
164+
#if defined(_WIN64)
165+
int fpstatus = _statusfp();
166+
#else
167+
/* windows enables sse on 32 bit, so check both flags */
168+
int fpstatus, fpstatus2;
169+
_statusfp2(&fpstatus, &fpstatus2);
170+
fpstatus |= fpstatus2;
171+
#endif
172+
return ((SW_ZERODIVIDE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
173+
((SW_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
174+
((SW_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
175+
((SW_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
176+
}
177+
178+
int npy_clear_floatstatus(void)
179+
{
180+
int fpstatus = npy_get_floatstatus();
181+
_clearfp();
182+
183+
return fpstatus;
184+
}
185+
186+
/* OSF/Alpha (Tru64) ---------------------------------------------*/
187+
#elif defined(__osf__) && defined(__alpha)
188+
189+
#include <machine/fpu.h>
190+
191+
int npy_get_floatstatus(void)
192+
{
193+
unsigned long fpstatus = ieee_get_fp_control();
194+
return ((IEEE_STATUS_DZE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
195+
((IEEE_STATUS_OVF & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
196+
((IEEE_STATUS_UNF & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
197+
((IEEE_STATUS_INV & fpstatus) ? NPY_FPE_INVALID : 0);
198+
}
199+
200+
int npy_clear_floatstatus(void)
201+
{
202+
long fpstatus = npy_get_floatstatus();
203+
/* clear status bits as well as disable exception mode if on */
204+
ieee_set_fp_control(0);
205+
206+
return fpstatus;
207+
}
208+
209+
#else
210+
211+
int npy_get_floatstatus(void)
212+
{
213+
return 0;
214+
}
215+
216+
int npy_clear_floatstatus(void)
217+
{
218+
return 0;
219+
}
220+
221+
#endif
222+
223+
/*
224+
* By using a volatile floating point value,
225+
* the compiler is forced to actually do the requested
226+
* operations because of potential concurrency.
227+
*
228+
* We shouldn't write multiple values to a single
229+
* global here, because that would cause
230+
* a race condition.
231+
*/
232+
static volatile double _npy_floatstatus_x,
233+
_npy_floatstatus_zero = 0.0, _npy_floatstatus_big = 1e300,
234+
_npy_floatstatus_small = 1e-300, _npy_floatstatus_inf;
235+
236+
void npy_set_floatstatus_divbyzero(void)
237+
{
238+
_npy_floatstatus_x = 1.0 / _npy_floatstatus_zero;
239+
}
240+
241+
void npy_set_floatstatus_overflow(void)
242+
{
243+
_npy_floatstatus_x = _npy_floatstatus_big * 1e300;
244+
}
245+
246+
void npy_set_floatstatus_underflow(void)
247+
{
248+
_npy_floatstatus_x = _npy_floatstatus_small * 1e-300;
249+
}
250+
251+
void npy_set_floatstatus_invalid(void)
252+
{
253+
_npy_floatstatus_inf = NPY_INFINITY;
254+
_npy_floatstatus_x = _npy_floatstatus_inf - NPY_INFINITY;
255+
}
256+
257+
#endif

0 commit comments

Comments
 (0)