fpetestmodule.c 5.74 KB
Newer Older
1
/*
2 3
     ---------------------------------------------------------------------
    /                       Copyright (c) 1996.                           \
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
   |          The Regents of the University of California.                 |
   |                        All rights reserved.                           |
   |                                                                       |
   |   Permission to use, copy, modify, and distribute this software for   |
   |   any purpose without fee is hereby granted, provided that this en-   |
   |   tire notice is included in all copies of any software which is or   |
   |   includes  a  copy  or  modification  of  this software and in all   |
   |   copies of the supporting documentation for such software.           |
   |                                                                       |
   |   This  work was produced at the University of California, Lawrence   |
   |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
   |   between  the  U.S.  Department  of  Energy and The Regents of the   |
   |   University of California for the operation of UC LLNL.              |
   |                                                                       |
   |                              DISCLAIMER                               |
   |                                                                       |
   |   This  software was prepared as an account of work sponsored by an   |
   |   agency of the United States Government. Neither the United States   |
   |   Government  nor the University of California nor any of their em-   |
   |   ployees, makes any warranty, express or implied, or  assumes  any   |
   |   liability  or  responsibility  for the accuracy, completeness, or   |
   |   usefulness of any information,  apparatus,  product,  or  process   |
   |   disclosed,   or  represents  that  its  use  would  not  infringe   |
   |   privately-owned rights. Reference herein to any specific  commer-   |
   |   cial  products,  process,  or  service  by trade name, trademark,   |
   |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
   |   imply  its endorsement, recommendation, or favoring by the United   |
   |   States Government or the University of California. The views  and   |
   |   opinions  of authors expressed herein do not necessarily state or   |
   |   reflect those of the United States Government or  the  University   |
   |   of  California,  and shall not be used for advertising or product   |
35 36
    \  endorsement purposes.                                              /
     ---------------------------------------------------------------------
37 38 39
*/

/*
40
                  Floating point exception test module.
41 42 43 44 45 46

 */

#include "Python.h"

static PyObject *fpe_error;
47 48

PyMODINIT_FUNC PyInit_fpetest(void);
49
static PyObject *test(PyObject *self,PyObject *args);
50 51 52 53
static double db0(double);
static double overflow(double);
static double nest1(int, double);
static double nest2(int, double);
54
static double nest3(double);
55
static void printerr(double);
56 57

static PyMethodDef fpetest_methods[] = {
58
    {"test",             (PyCFunction) test,             METH_VARARGS},
59 60 61 62 63
    {0,0}
};

static PyObject *test(PyObject *self,PyObject *args)
{
64
    double r;
65

66 67 68
    fprintf(stderr,"overflow");
    r = overflow(1.e160);
    printerr(r);
69

70 71 72
    fprintf(stderr,"\ndiv by 0");
    r = db0(0.0);
    printerr(r);
73

74 75 76
    fprintf(stderr,"\nnested outer");
    r = nest1(0, 0.0);
    printerr(r);
77

78 79 80
    fprintf(stderr,"\nnested inner");
    r = nest1(1, 1.0);
    printerr(r);
81

82 83 84
    fprintf(stderr,"\ntrailing outer");
    r = nest1(2, 2.0);
    printerr(r);
85

86 87 88
    fprintf(stderr,"\nnested prior");
    r = nest2(0, 0.0);
    printerr(r);
89

90 91 92 93 94 95 96
    fprintf(stderr,"\nnested interior");
    r = nest2(1, 1.0);
    printerr(r);

    fprintf(stderr,"\nnested trailing");
    r = nest2(2, 2.0);
    printerr(r);
97 98 99 100 101

    Py_INCREF (Py_None);
    return Py_None;
}

102 103 104 105 106 107 108 109 110 111 112 113
static void printerr(double r)
{
    if(r == 3.1416){
      fprintf(stderr,"\tPASS\n");
      PyErr_Print();
    }else{
      fprintf(stderr,"\tFAIL\n");
    }
    PyErr_Clear();
}

static double nest1(int i, double x)
114 115
{
  double a = 1.0;
116 117 118 119 120 121 122

  PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
  if(i == 0){
    a = 1./x;
  }else if(i == 1){
    /* This (following) message is never seen. */
    PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
123
    a = 1./(1. - x);
124
    PyFPE_END_PROTECT(a)
125 126 127
  }else if(i == 2){
    a = 1./(2. - x);
  }
128
  PyFPE_END_PROTECT(a)
129 130

  return a;
131 132
}

133
static double nest2(int i, double x)
134 135
{
  double a = 1.0;
136 137 138 139 140 141 142 143
  PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
  if(i == 0){
    a = 1./x;
  }else if(i == 1){
    a = nest3(x);
  }else if(i == 2){
    a = 1./(2. - x);
  }
144
  PyFPE_END_PROTECT(a)
145
  return a;
146 147 148 149 150
}

static double nest3(double x)
{
  double result;
151 152
  /* This (following) message is never seen. */
  PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
153
  result = 1./(1. - x);
154
  PyFPE_END_PROTECT(result)
155 156 157
  return result;
}

158
static double db0(double x)
159
{
160 161 162
  double a;
  PyFPE_START_PROTECT("Division by zero", return 3.1416)
  a = 1./x;
163
  PyFPE_END_PROTECT(a)
164
  return a;
165 166
}

167
static double overflow(double b)
168
{
169 170
  double a;
  PyFPE_START_PROTECT("Overflow", return 3.1416)
171
  a = b*b;
172
  PyFPE_END_PROTECT(a)
173
  return a;
174 175
}

176
static struct PyModuleDef fpetestmodule = {
177 178 179 180 181 182 183 184 185
    PyModuleDef_HEAD_INIT,
    "fpetest",
    NULL,
    -1,
    fpetest_methods,
    NULL,
    NULL,
    NULL,
    NULL
186 187 188
};

PyMODINIT_FUNC PyInit_fpetest(void)
189 190 191
{
    PyObject *m, *d;

192
    m = PyModule_Create(&fpetestmodule);
193
    if (m == NULL)
194
    return NULL;
195
    d = PyModule_GetDict(m);
196 197
    fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
    if (fpe_error != NULL)
198
        PyDict_SetItemString(d, "error", fpe_error);
199
    return m;
200
}