master xplshn/aruu / cmd / posix / awk / math.c
  1/****************************************************************
  2Copyright (C) Lucent Technologies 1997
  3All Rights Reserved
  4
  5Permission to use, copy, modify, and distribute this software and
  6its documentation for any purpose and without fee is hereby
  7granted, provided that the above copyright notice appear in all
  8copies and that both that the copyright notice and this
  9permission notice and warranty disclaimer appear in supporting
 10documentation, and that the name Lucent Technologies or any of
 11its entities not be used in advertising or publicity pertaining
 12to distribution of the software without specific, written prior
 13permission.
 14
 15LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 16INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 17IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 18SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 20IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 21ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 22THIS 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}