summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/npymath/ieee754.cpp244
1 files changed, 5 insertions, 239 deletions
diff --git a/numpy/core/src/npymath/ieee754.cpp b/numpy/core/src/npymath/ieee754.cpp
index 81573d97a..2244004c0 100644
--- a/numpy/core/src/npymath/ieee754.cpp
+++ b/numpy/core/src/npymath/ieee754.cpp
@@ -646,245 +646,13 @@ npy_get_floatstatus()
return npy_get_floatstatus_barrier(&x);
}
-/*
- * Functions to set the floating point status word.
- */
-
-#if (defined(__unix__) || defined(unix)) && !defined(USG)
-#include <sys/param.h>
-#endif
-
-/*
- * Define floating point status functions. We must define
- * npy_get_floatstatus_barrier, npy_clear_floatstatus_barrier,
- * npy_set_floatstatus_{divbyzero, overflow, underflow, invalid}
- * for all supported platforms.
- */
-
-/* Solaris --------------------------------------------------------*/
-/* --------ignoring SunOS ieee_flags approach, someone else can
-** deal with that! */
-#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
- (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
- defined(__NetBSD__)
-#include <ieeefp.h>
-
-extern "C" int
-npy_get_floatstatus_barrier(char *param)
-{
- int fpstatus = fpgetsticky();
- /*
- * By using a volatile, the compiler cannot reorder this call
- */
- if (param != NULL) {
- volatile char NPY_UNUSED(c) = *(char *)param;
- }
- return ((FP_X_DZ & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
- ((FP_X_OFL & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
- ((FP_X_UFL & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
- ((FP_X_INV & fpstatus) ? NPY_FPE_INVALID : 0);
-}
-
-extern "C" int
-npy_clear_floatstatus_barrier(char *param)
-{
- int fpstatus = npy_get_floatstatus_barrier(param);
- fpsetsticky(0);
-
- return fpstatus;
-}
-
-extern "C" void
-npy_set_floatstatus_divbyzero(void)
-{
- fpsetsticky(FP_X_DZ);
-}
-
-extern "C" void
-npy_set_floatstatus_overflow(void)
-{
- fpsetsticky(FP_X_OFL);
-}
-
-extern "C" void
-npy_set_floatstatus_underflow(void)
-{
- fpsetsticky(FP_X_UFL);
-}
-
-extern "C" void
-npy_set_floatstatus_invalid(void)
-{
- fpsetsticky(FP_X_INV);
-}
-
-#elif defined(_AIX) && !defined(__GNUC__)
-#include <cfloat>
-#include <fpxcp.h>
-
-extern "C" int
-npy_get_floatstatus_barrier(char *param)
-{
- int fpstatus = fp_read_flag();
- /*
- * By using a volatile, the compiler cannot reorder this call
- */
- if (param != NULL) {
- volatile char NPY_UNUSED(c) = *(char *)param;
- }
- return ((FP_DIV_BY_ZERO & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
- ((FP_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
- ((FP_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
- ((FP_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
-}
-
-extern "C" int
-npy_clear_floatstatus_barrier(char *param)
-{
- int fpstatus = npy_get_floatstatus_barrier(param);
- fp_swap_flag(0);
-
- return fpstatus;
-}
-
-extern "C" void
-npy_set_floatstatus_divbyzero(void)
-{
- fp_raise_xcp(FP_DIV_BY_ZERO);
-}
-
-extern "C" void
-npy_set_floatstatus_overflow(void)
-{
- fp_raise_xcp(FP_OVERFLOW);
-}
-
-extern "C" void
-npy_set_floatstatus_underflow(void)
-{
- fp_raise_xcp(FP_UNDERFLOW);
-}
-
-extern "C" void
-npy_set_floatstatus_invalid(void)
-{
- fp_raise_xcp(FP_INVALID);
-}
-
-#elif defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) || \
- defined(__UCLIBC__) || (defined(__arc__) && defined(__GLIBC__))
-/*
- * By using a volatile floating point value,
- * the compiler is forced to actually do the requested
- * operations because of potential concurrency.
- *
- * We shouldn't write multiple values to a single
- * global here, because that would cause
- * a race condition.
+/*
+ * General C99 code for floating point error handling. These functions mainly
+ * exists, because `fenv.h` was not standardized in C89 so they gave better
+ * portability. This should be unnecessary with C99/C++11 and further
+ * functionality can be used from `fenv.h` directly.
*/
-static volatile double _npy_floatstatus_x,
- _npy_floatstatus_zero = 0.0, _npy_floatstatus_big = 1e300,
- _npy_floatstatus_small = 1e-300, _npy_floatstatus_inf;
-
-extern "C" void
-npy_set_floatstatus_divbyzero(void)
-{
- _npy_floatstatus_x = 1.0 / _npy_floatstatus_zero;
-}
-
-extern "C" void
-npy_set_floatstatus_overflow(void)
-{
- _npy_floatstatus_x = _npy_floatstatus_big * 1e300;
-}
-
-extern "C" void
-npy_set_floatstatus_underflow(void)
-{
- _npy_floatstatus_x = _npy_floatstatus_small * 1e-300;
-}
-
-extern "C" void
-npy_set_floatstatus_invalid(void)
-{
- _npy_floatstatus_inf = NPY_INFINITY;
- _npy_floatstatus_x = _npy_floatstatus_inf - NPY_INFINITY;
-}
-
-/* MS Windows -----------------------------------------------------*/
-#if defined(_MSC_VER)
-
-#include <cfloat>
-
-extern "C" int
-npy_get_floatstatus_barrier(char *param)
-{
- /*
- * By using a volatile, the compiler cannot reorder this call
- */
-#if defined(_WIN64)
- int fpstatus = _statusfp();
-#else
- /* windows enables sse on 32 bit, so check both flags */
- unsigned int fpstatus, fpstatus2;
- _statusfp2(&fpstatus, &fpstatus2);
- fpstatus |= fpstatus2;
-#endif
- if (param != NULL) {
- volatile char NPY_UNUSED(c) = *(char *)param;
- }
- return ((SW_ZERODIVIDE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
- ((SW_OVERFLOW & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
- ((SW_UNDERFLOW & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
- ((SW_INVALID & fpstatus) ? NPY_FPE_INVALID : 0);
-}
-
-extern "C" int
-npy_clear_floatstatus_barrier(char *param)
-{
- int fpstatus = npy_get_floatstatus_barrier(param);
- _clearfp();
-
- return fpstatus;
-}
-
-/* OSF/Alpha (Tru64) ---------------------------------------------*/
-#elif defined(__osf__) && defined(__alpha)
-
-#include <machine/fpu.h>
-
-extern "C" int
-npy_get_floatstatus_barrier(char *param)
-{
- unsigned long fpstatus = ieee_get_fp_control();
- /*
- * By using a volatile, the compiler cannot reorder this call
- */
- if (param != NULL) {
- volatile char NPY_UNUSED(c) = *(char *)param;
- }
- return ((IEEE_STATUS_DZE & fpstatus) ? NPY_FPE_DIVIDEBYZERO : 0) |
- ((IEEE_STATUS_OVF & fpstatus) ? NPY_FPE_OVERFLOW : 0) |
- ((IEEE_STATUS_UNF & fpstatus) ? NPY_FPE_UNDERFLOW : 0) |
- ((IEEE_STATUS_INV & fpstatus) ? NPY_FPE_INVALID : 0);
-}
-
-extern "C" int
-npy_clear_floatstatus_barrier(char *param)
-{
- int fpstatus = npy_get_floatstatus_barrier(param);
- /* clear status bits as well as disable exception mode if on */
- ieee_set_fp_control(0);
-
- return fpstatus;
-}
-
-#endif
-/* End of defined(_MSC_VER) || (defined(__osf__) && defined(__alpha)) */
-
-#else
-/* General GCC code, should work on most platforms */
#include <fenv.h>
extern "C" int
@@ -940,5 +708,3 @@ npy_set_floatstatus_invalid(void)
{
feraiseexcept(FE_INVALID);
}
-
-#endif