1/* ***************************************************************
2 * copyright (c) lucent technologies 1997
3 * all rights reserved
4 *
5 * permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby
7 * granted, provided that the above copyright notice appear in all
8 * copies and that both that the copyright notice and this
9 * permission notice and warranty disclaimer appear in supporting
10 * documentation, and that the name lucent technologies or any of
11 * its entities not be used in advertising or publicity pertaining
12 * to distribution of the software without specific, written prior
13 * permission
14 *
15 * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 * THIS SOFTWARE
23 * ************************************************************** */
24
25#ifdef __GNUC__
26#pragma GCC diagnostic ignored "-Wunknown-pragmas"
27#endif
28#pragma STDC FENV_ACCESS ON
29
30#include <errno.h>
31#include <fenv.h>
32#include <math.h>
33#include <stdio.h>
34
35#include "awk.h"
36
37#ifndef FE_DIVBYZERO
38#define FE_DIVBYZERO 0
39#endif
40
41#ifndef FE_INVALID
42#define FE_INVALID 0
43#endif
44
45#ifndef FE_OVERFLOW
46#define FE_OVERFLOW 0
47#endif
48
49#ifndef FE_UNDERFLOW
50#define FE_UNDERFLOW 0
51#endif
52
53#define errclear() \
54 do { \
55 errno = 0; \
56 feclearexcept(FE_ALL_EXCEPT); \
57 } while (0)
58
59static double
60errcheck(double x, const char *s)
61{
62 if (errno == EDOM || fetestexcept(FE_INVALID)) {
63 errno = 0;
64 WARNING("%s argument out of domain", s);
65 x = 1;
66 } else if (errno == ERANGE || fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) {
67 errno = 0;
68 WARNING("%s result out of range", s);
69 x = 1;
70 }
71
72 return x;
73}
74
75double
76exp_errcheck(double x)
77{
78 errclear();
79 return errcheck(exp(x), "exp");
80}
81
82double
83log_errcheck(double x)
84{
85 errclear();
86 return errcheck(log(x), "log");
87}
88
89double
90pow_errcheck(double x, double y)
91{
92 errclear();
93 return errcheck(pow(x, y), "pow");
94}
95
96double
97sqrt_errcheck(double x)
98{
99 errclear();
100 return errcheck(sqrt(x), "sqrt");
101}