1 /* Check for underflow and force underflow exceptions. 2 Copyright (C) 2015-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _MATH_UNDERFLOW_H 20 #define _MATH_UNDERFLOW_H 1 21 22 #include <float.h> 23 #include <math.h> 24 25 #include <math-barriers.h> 26 27 #define fabs_tg(x) __MATH_TG ((x), (__typeof (x)) __builtin_fabs, (x)) 28 29 /* These must be function-like macros because some __MATH_TG 30 implementations macro-expand the function-name argument before 31 concatenating a suffix to it. */ 32 #define min_of_type_f() FLT_MIN 33 #define min_of_type_() DBL_MIN 34 #define min_of_type_l() LDBL_MIN 35 #define min_of_type_f128() FLT128_MIN 36 37 #define min_of_type(x) __MATH_TG ((x), (__typeof (x)) min_of_type_, ()) 38 39 /* If X (which is not a NaN) is subnormal, force an underflow 40 exception. */ 41 #define math_check_force_underflow(x) \ 42 do \ 43 { \ 44 __typeof (x) force_underflow_tmp = (x); \ 45 if (fabs_tg (force_underflow_tmp) \ 46 < min_of_type (force_underflow_tmp)) \ 47 { \ 48 __typeof (force_underflow_tmp) force_underflow_tmp2 \ 49 = force_underflow_tmp * force_underflow_tmp; \ 50 math_force_eval (force_underflow_tmp2); \ 51 } \ 52 } \ 53 while (0) 54 /* Likewise, but X is also known to be nonnegative. */ 55 #define math_check_force_underflow_nonneg(x) \ 56 do \ 57 { \ 58 __typeof (x) force_underflow_tmp = (x); \ 59 if (force_underflow_tmp \ 60 < min_of_type (force_underflow_tmp)) \ 61 { \ 62 __typeof (force_underflow_tmp) force_underflow_tmp2 \ 63 = force_underflow_tmp * force_underflow_tmp; \ 64 math_force_eval (force_underflow_tmp2); \ 65 } \ 66 } \ 67 while (0) 68 /* Likewise, for both real and imaginary parts of a complex 69 result. */ 70 #define math_check_force_underflow_complex(x) \ 71 do \ 72 { \ 73 __typeof (x) force_underflow_complex_tmp = (x); \ 74 math_check_force_underflow (__real__ force_underflow_complex_tmp); \ 75 math_check_force_underflow (__imag__ force_underflow_complex_tmp); \ 76 } \ 77 while (0) 78 79 #endif /* math-underflow.h */ 80