(root)/
glibc-2.38/
sysdeps/
ieee754/
dbl-64/
math_err.c
       1  /* Double-precision math error handling.
       2     Copyright (C) 2018-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  #include <math-barriers.h>
      20  #include "math_config.h"
      21  
      22  #if WANT_ERRNO
      23  #include <errno.h>
      24  /* NOINLINE reduces code size and avoids making math functions non-leaf
      25     when the error handling is inlined.  */
      26  NOINLINE static double
      27  with_errno (double y, int e)
      28  {
      29    errno = e;
      30    return y;
      31  }
      32  #else
      33  #define with_errno(x, e) (x)
      34  #endif
      35  
      36  attribute_hidden double
      37  __math_edom (double y)
      38  {
      39    return with_errno (y, EDOM);
      40  }
      41  
      42  /* NOINLINE reduces code size.  */
      43  NOINLINE static double
      44  xflow (uint32_t sign, double y)
      45  {
      46    y = math_opt_barrier (sign ? -y : y) * y;
      47    return with_errno (y, ERANGE);
      48  }
      49  
      50  attribute_hidden double
      51  __math_uflow (uint32_t sign)
      52  {
      53    return xflow (sign, 0x1p-767);
      54  }
      55  
      56  #if WANT_ERRNO_UFLOW
      57  /* Underflows to zero in some non-nearest rounding mode, setting errno
      58     is valid even if the result is non-zero, but in the subnormal range.  */
      59  attribute_hidden double
      60  __math_may_uflow (uint32_t sign)
      61  {
      62    return xflow (sign, 0x1.8p-538);
      63  }
      64  #endif
      65  
      66  attribute_hidden double
      67  __math_oflow (uint32_t sign)
      68  {
      69    return xflow (sign, 0x1p769);
      70  }
      71  
      72  attribute_hidden double
      73  __math_divzero (uint32_t sign)
      74  {
      75    double y = math_opt_barrier (sign ? -1.0 : 1.0) / 0.0;
      76    return with_errno (y, ERANGE);
      77  }
      78  
      79  attribute_hidden double
      80  __math_invalid (double x)
      81  {
      82    double y = (x - x) / (x - x);
      83    return isnan (x) ? y : with_errno (y, EDOM);
      84  }
      85  
      86  /* Check result and set errno if necessary.  */
      87  
      88  attribute_hidden double
      89  __math_check_uflow (double y)
      90  {
      91    return y == 0.0 ? with_errno (y, ERANGE) : y;
      92  }
      93  
      94  attribute_hidden double
      95  __math_check_oflow (double y)
      96  {
      97    return isinf (y) ? with_errno (y, ERANGE) : y;
      98  }