(root)/
glibc-2.38/
sysdeps/
ieee754/
flt-32/
math_config.h
       1  /* Configuration for math routines.
       2     Copyright (C) 2017-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_CONFIG_H
      20  #define _MATH_CONFIG_H
      21  
      22  #include <math.h>
      23  #include <math_private.h>
      24  #include <nan-high-order-bit.h>
      25  #include <stdint.h>
      26  
      27  #ifndef WANT_ROUNDING
      28  /* Correct special case results in non-nearest rounding modes.  */
      29  # define WANT_ROUNDING 1
      30  #endif
      31  #ifndef WANT_ERRNO
      32  /* Set errno according to ISO C with (math_errhandling & MATH_ERRNO) != 0.  */
      33  # define WANT_ERRNO 1
      34  #endif
      35  #ifndef WANT_ERRNO_UFLOW
      36  /* Set errno to ERANGE if result underflows to 0 (in all rounding modes).  */
      37  # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO)
      38  #endif
      39  
      40  #ifndef TOINT_INTRINSICS
      41  /* When set, the roundtoint and converttoint functions are provided with
      42     the semantics documented below.  */
      43  # define TOINT_INTRINSICS 0
      44  #endif
      45  
      46  #if TOINT_INTRINSICS
      47  /* Round x to nearest int in all rounding modes, ties have to be rounded
      48     consistently with converttoint so the results match.  If the result
      49     would be outside of [-2^31, 2^31-1] then the semantics is unspecified.  */
      50  static inline double_t
      51  roundtoint (double_t x);
      52  
      53  /* Convert x to nearest int in all rounding modes, ties have to be rounded
      54     consistently with roundtoint.  If the result is not representible in an
      55     int32_t then the semantics is unspecified.  */
      56  static inline int32_t
      57  converttoint (double_t x);
      58  #endif
      59  
      60  static inline uint32_t
      61  asuint (float f)
      62  {
      63    union
      64    {
      65      float f;
      66      uint32_t i;
      67    } u = {f};
      68    return u.i;
      69  }
      70  
      71  static inline float
      72  asfloat (uint32_t i)
      73  {
      74    union
      75    {
      76      uint32_t i;
      77      float f;
      78    } u = {i};
      79    return u.f;
      80  }
      81  
      82  static inline uint64_t
      83  asuint64 (double f)
      84  {
      85    union
      86    {
      87      double f;
      88      uint64_t i;
      89    } u = {f};
      90    return u.i;
      91  }
      92  
      93  static inline double
      94  asdouble (uint64_t i)
      95  {
      96    union
      97    {
      98      uint64_t i;
      99      double f;
     100    } u = {i};
     101    return u.f;
     102  }
     103  
     104  static inline int
     105  issignalingf_inline (float x)
     106  {
     107    uint32_t ix = asuint (x);
     108    if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
     109      return (ix & 0x7fc00000) == 0x7fc00000;
     110    return 2 * (ix ^ 0x00400000) > 2 * 0x7fc00000UL;
     111  }
     112  
     113  #define BIT_WIDTH       32
     114  #define MANTISSA_WIDTH  23
     115  #define EXPONENT_WIDTH  8
     116  #define MANTISSA_MASK   0x007fffff
     117  #define EXPONENT_MASK   0x7f800000
     118  #define EXP_MANT_MASK   0x7fffffff
     119  #define QUIET_NAN_MASK  0x00400000
     120  #define SIGN_MASK       0x80000000
     121  
     122  static inline bool
     123  is_nan (uint32_t x)
     124  {
     125    return (x & EXP_MANT_MASK) > EXPONENT_MASK;
     126  }
     127  
     128  static inline uint32_t
     129  get_mantissa (uint32_t x)
     130  {
     131    return x & MANTISSA_MASK;
     132  }
     133  
     134  /* Convert integer number X, unbiased exponent EP, and sign S to double:
     135  
     136     result = X * 2^(EP+1 - exponent_bias)
     137  
     138     NB: zero is not supported.  */
     139  static inline double
     140  make_float (uint32_t x, int ep, uint32_t s)
     141  {
     142    int lz = __builtin_clz (x) - EXPONENT_WIDTH;
     143    x <<= lz;
     144    ep -= lz;
     145  
     146    if (__glibc_unlikely (ep < 0 || x == 0))
     147      {
     148        x >>= -ep;
     149        ep = 0;
     150      }
     151    return asfloat (s + x + (ep << MANTISSA_WIDTH));
     152  }
     153  
     154  attribute_hidden float __math_oflowf (uint32_t);
     155  attribute_hidden float __math_uflowf (uint32_t);
     156  attribute_hidden float __math_may_uflowf (uint32_t);
     157  attribute_hidden float __math_divzerof (uint32_t);
     158  attribute_hidden float __math_invalidf (float);
     159  attribute_hidden float __math_edomf (float x);
     160  
     161  /* Shared between expf, exp2f, exp10f, and powf.  */
     162  #define EXP2F_TABLE_BITS 5
     163  #define EXP2F_POLY_ORDER 3
     164  extern const struct exp2f_data
     165  {
     166    uint64_t tab[1 << EXP2F_TABLE_BITS];
     167    double shift_scaled;
     168    double poly[EXP2F_POLY_ORDER];
     169    double shift;
     170    double invln2_scaled;
     171    double poly_scaled[EXP2F_POLY_ORDER];
     172  } __exp2f_data attribute_hidden;
     173  
     174  #define LOGF_TABLE_BITS 4
     175  #define LOGF_POLY_ORDER 4
     176  extern const struct logf_data
     177  {
     178    struct
     179    {
     180      double invc, logc;
     181    } tab[1 << LOGF_TABLE_BITS];
     182    double ln2;
     183    double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1.  */
     184  } __logf_data attribute_hidden;
     185  
     186  #define LOG2F_TABLE_BITS 4
     187  #define LOG2F_POLY_ORDER 4
     188  extern const struct log2f_data
     189  {
     190    struct
     191    {
     192      double invc, logc;
     193    } tab[1 << LOG2F_TABLE_BITS];
     194    double poly[LOG2F_POLY_ORDER];
     195  } __log2f_data attribute_hidden;
     196  
     197  #define POWF_LOG2_TABLE_BITS 4
     198  #define POWF_LOG2_POLY_ORDER 5
     199  #if TOINT_INTRINSICS
     200  # define POWF_SCALE_BITS EXP2F_TABLE_BITS
     201  #else
     202  # define POWF_SCALE_BITS 0
     203  #endif
     204  #define POWF_SCALE ((double) (1 << POWF_SCALE_BITS))
     205  extern const struct powf_log2_data
     206  {
     207    struct
     208    {
     209      double invc, logc;
     210    } tab[1 << POWF_LOG2_TABLE_BITS];
     211    double poly[POWF_LOG2_POLY_ORDER];
     212  } __powf_log2_data attribute_hidden;
     213  
     214  #endif