(root)/
glibc-2.38/
math/
math-underflow.h
       1  /* Check for underflow and force underflow exceptions.
       2     Copyright (C) 2015-2023 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 */