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

source code of glibc/math/math-underflow.h