1  /*
2       ---------------------------------------------------------------------
3      /                       Copyright (c) 1996.                           \
4     |          The Regents of the University of California.                 |
5     |                        All rights reserved.                           |
6     |                                                                       |
7     |   Permission to use, copy, modify, and distribute this software for   |
8     |   any purpose without fee is hereby granted, provided that this en-   |
9     |   tire notice is included in all copies of any software which is or   |
10     |   includes  a  copy  or  modification  of  this software and in all   |
11     |   copies of the supporting documentation for such software.           |
12     |                                                                       |
13     |   This  work was produced at the University of California, Lawrence   |
14     |   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
15     |   between  the  U.S.  Department  of  Energy and The Regents of the   |
16     |   University of California for the operation of UC LLNL.              |
17     |                                                                       |
18     |                              DISCLAIMER                               |
19     |                                                                       |
20     |   This  software was prepared as an account of work sponsored by an   |
21     |   agency of the United States Government. Neither the United States   |
22     |   Government  nor the University of California nor any of their em-   |
23     |   ployees, makes any warranty, express or implied, or  assumes  any   |
24     |   liability  or  responsibility  for the accuracy, completeness, or   |
25     |   usefulness of any information,  apparatus,  product,  or  process   |
26     |   disclosed,   or  represents  that  its  use  would  not  infringe   |
27     |   privately-owned rights. Reference herein to any specific  commer-   |
28     |   cial  products,  process,  or  service  by trade name, trademark,   |
29     |   manufacturer, or otherwise, does not  necessarily  constitute  or   |
30     |   imply  its endorsement, recommendation, or favoring by the United   |
31     |   States Government or the University of California. The views  and   |
32     |   opinions  of authors expressed herein do not necessarily state or   |
33     |   reflect those of the United States Government or  the  University   |
34     |   of  California,  and shall not be used for advertising or product   |
35      \  endorsement purposes.                                              /
36       ---------------------------------------------------------------------
37  */
38  
39  /*
40  		  Floating point exception test module.
41  
42   */
43  
44  #include "Python.h"
45  
46  static PyObject *fpe_error;
47  PyMODINIT_FUNC initfpetest(void);
48  static PyObject *test(PyObject *self,PyObject *args);
49  static double db0(double);
50  static double overflow(double);
51  static double nest1(int, double);
52  static double nest2(int, double);
53  static double nest3(double);
54  static void printerr(double);
55  
56  static PyMethodDef fpetest_methods[] = {
57      {"test",		 (PyCFunction) test,		 METH_VARARGS},
58      {0,0}
59  };
60  
test(PyObject * self,PyObject * args)61  static PyObject *test(PyObject *self,PyObject *args)
62  {
63      double r;
64  
65      fprintf(stderr,"overflow");
66      r = overflow(1.e160);
67      printerr(r);
68  
69      fprintf(stderr,"\ndiv by 0");
70      r = db0(0.0);
71      printerr(r);
72  
73      fprintf(stderr,"\nnested outer");
74      r = nest1(0, 0.0);
75      printerr(r);
76  
77      fprintf(stderr,"\nnested inner");
78      r = nest1(1, 1.0);
79      printerr(r);
80  
81      fprintf(stderr,"\ntrailing outer");
82      r = nest1(2, 2.0);
83      printerr(r);
84  
85      fprintf(stderr,"\nnested prior");
86      r = nest2(0, 0.0);
87      printerr(r);
88  
89      fprintf(stderr,"\nnested interior");
90      r = nest2(1, 1.0);
91      printerr(r);
92  
93      fprintf(stderr,"\nnested trailing");
94      r = nest2(2, 2.0);
95      printerr(r);
96  
97      Py_INCREF (Py_None);
98      return Py_None;
99  }
100  
printerr(double r)101  static void printerr(double r)
102  {
103      if(r == 3.1416){
104        fprintf(stderr,"\tPASS\n");
105        PyErr_Print();
106      }else{
107        fprintf(stderr,"\tFAIL\n");
108      }
109      PyErr_Clear();
110  }
111  
nest1(int i,double x)112  static double nest1(int i, double x)
113  {
114    double a = 1.0;
115  
116    PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
117    if(i == 0){
118      a = 1./x;
119    }else if(i == 1){
120      /* This (following) message is never seen. */
121      PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
122      a = 1./(1. - x);
123      PyFPE_END_PROTECT(a)
124    }else if(i == 2){
125      a = 1./(2. - x);
126    }
127    PyFPE_END_PROTECT(a)
128  
129    return a;
130  }
131  
nest2(int i,double x)132  static double nest2(int i, double x)
133  {
134    double a = 1.0;
135    PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
136    if(i == 0){
137      a = 1./x;
138    }else if(i == 1){
139      a = nest3(x);
140    }else if(i == 2){
141      a = 1./(2. - x);
142    }
143    PyFPE_END_PROTECT(a)
144    return a;
145  }
146  
nest3(double x)147  static double nest3(double x)
148  {
149    double result;
150    /* This (following) message is never seen. */
151    PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
152    result = 1./(1. - x);
153    PyFPE_END_PROTECT(result)
154    return result;
155  }
156  
db0(double x)157  static double db0(double x)
158  {
159    double a;
160    PyFPE_START_PROTECT("Division by zero", return 3.1416)
161    a = 1./x;
162    PyFPE_END_PROTECT(a)
163    return a;
164  }
165  
overflow(double b)166  static double overflow(double b)
167  {
168    double a;
169    PyFPE_START_PROTECT("Overflow", return 3.1416)
170    a = b*b;
171    PyFPE_END_PROTECT(a)
172    return a;
173  }
174  
initfpetest(void)175  PyMODINIT_FUNC initfpetest(void)
176  {
177      PyObject *m, *d;
178  
179      m = Py_InitModule("fpetest", fpetest_methods);
180      if (m == NULL)
181      	return;
182      d = PyModule_GetDict(m);
183      fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
184      if (fpe_error != NULL)
185  	    PyDict_SetItemString(d, "error", fpe_error);
186  }
187