/* Copyright (C) 2014-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3mafpe.ctr */ #ifndef DK3MAFPE_H_INCLUDED /** Avoid multiple inclusions. */ #define DK3MAFPE_H_INCLUDED 1 #line 9 "dk3mafpe.ctr" /** @file dk3mafpe.h Floating point exception handling. Before doing any floating point calculation, use dk3mafpe_get_handling_type() to check whether an exception handling mechanism is available. The function returns DK3_MA_FPE_HANDLING_CLEARFP on Windows systems if _clearfp() and _statusfp() are available. It returns DK3_MA_FPE_HANDLING_FETESTEXCEPT if the POSIX floating point exception functions fetestexcept() and feclearexcept() are available. If none of these mechanisms is available, DK3_MA_FPE_HANDLING_NONE is returned. Your program should issue a warning. Before doing a floating point calculation use dk3mafpe_clear() to clear the FPU status word. After doing a floating point calculation use dk3mafpe_get() or dk3mafpe_get_and_clear() to retrieve the status word. Check the status word against DK3MAFPE_ALL (and-combine them) to see if any exception occured. If your calculation results in just one double you can use dk3mafpe_isfinite() and/or dk3mafpe_isnormal() to check the value. If the dk3mafpe_isfinite() test fails, the value is of no use. If the dk3mafpe_isnormal() test fails, the result is very small, it uses denormalized representation and has probably and likely lost much of it's precision. */ #include #if DK3_HAVE_FLOAT_H #include #endif #if DK3_HAVE_FENV_H #include #endif #if DK3_ON_WINDOWS /** Floating point exceptions set. */ typedef unsigned int dk3_ma_fpe_t; #if DK3_HAVE__CLEARFP /** Division by 0. */ #define DK3MAFPE_DIVBYZERO (_SW_ZERODIVIDE) /** Inexact result (either overflow or underflow). */ #define DK3MAFPE_INEXACT (_SW_INEXACT) /** Not a number (0/0 or infty - infty). */ #define DK3MAFPE_INVALID (_SW_INVALID) /** Result too large for representation. */ #define DK3MAFPE_OVERFLOW (_SW_OVERFLOW) /** Result too small for normalized representation. */ #define DK3MAFPE_UNDERFLOW (_SW_UNDERFLOW) /** Denormalized number. */ #define DK3MAFPE_DENORMAL (_SW_DENORMAL) /** Or-combination of all supported exceptions. */ #define DK3MAFPE_ALL \ ((_SW_ZERODIVIDE) \ | (_SW_INEXACT) \ | (_SW_INVALID) \ | (_SW_OVERFLOW) \ | (_SW_UNDERFLOW) \ | (_SW_DENORMAL)) #else /** Division by 0. */ #define DK3MAFPE_DIVBYZERO 0 /** Inexact result (either overflow or underflow). */ #define DK3MAFPE_INEXACT 0 /** Not a number (0/0 or infty - infty). */ #define DK3MAFPE_INVALID 0 /** Result too large for representation. */ #define DK3MAFPE_OVERFLOW 0 /** Result too small for normalized representation. */ #define DK3MAFPE_UNDERFLOW 0 /** Denormalized number. */ #define DK3MAFPE_DENORMAL 0 /** Or-combination of all supported exceptions. */ #define DK3MAFPE_ALL 0 #endif #else /** Floating point exceptions set. */ typedef int dk3_ma_fpe_t; #if DK3_HAVE_FETESTEXCEPT /** Division by 0. */ #define DK3MAFPE_DIVBYZERO (FE_DIVBYZERO) /** Inexact result (either overflow or underflow). */ #define DK3MAFPE_INEXACT (FE_INEXACT) /** Not a number (0/0 or infty - infty). */ #define DK3MAFPE_INVALID (FE_INVALID) /** Result too large for representation. */ #define DK3MAFPE_OVERFLOW (FE_OVERFLOW) /** Result too small for normalized representation. */ #define DK3MAFPE_UNDERFLOW (FE_UNDERFLOW) /** Denormalized number. */ #define DK3MAFPE_DENORMAL 0 /** Or-combination of all supported exceptions. */ #define DK3MAFPE_ALL (FE_ALL_EXCEPT) #else /** Division by 0. */ #define DK3MAFPE_DIVBYZERO 0 /** Inexact result (either overflow or underflow). */ #define DK3MAFPE_INEXACT 0 /** Not a number (0/0 or infty - infty). */ #define DK3MAFPE_INVALID 0 /** Result too large for representation. */ #define DK3MAFPE_OVERFLOW 0 /** Result too small for normalized representation. */ #define DK3MAFPE_UNDERFLOW 0 /** Denormalized number. */ #define DK3MAFPE_DENORMAL 0 /** Or-combination of all supported exceptions. */ #define DK3MAFPE_ALL 0 #endif #endif /** Different handling types for floating point exceptions. */ enum { /** No fpe exception handling available. */ DK3_MA_FPE_HANDLING_NONE = 0, /** POSIX exception handling using fetestexcept() and friends. */ DK3_MA_FPE_HANDLING_FETESTEXCEPT, /** Windows exception handling using _clearfp() and friends. */ DK3_MA_FPE_HANDLING_CLEARFP }; #ifdef __cplusplus extern "C" { #endif /** Retrieve exception set. @return Exceptions found. */ dk3_ma_fpe_t dk3mafpe_get(void); /** Clear exception set. */ void dk3mafpe_clear(void); /** Retrieve exception set and clear. @return Exceptions found. */ dk3_ma_fpe_t dk3mafpe_get_and_clear(void); /** Get exception handling type. @return One from DK3_MA_FPE_HANDLING_NONE, DK3_MA_FPE_HANDLING_FETESTEXCEPT, DK3_MA_FPE_HANDLING_CLEARFP. */ int dk3mafpe_get_handling_type(void); /** Check whether a number is normalized. @param x Number to check. @return Non-null result on success, 0 on error. */ int dk3mafpe_isnormal(double x); /** Check whether a number is finite (not NAN, not INF). @param x Number to check. @return Non-null result on success, 0 on error. */ int dk3mafpe_isfinite(double x); #ifdef __cplusplus } #endif #endif