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 
48 PyMODINIT_FUNC PyInit_fpetest(void);
49 static PyObject *test(PyObject *self,PyObject *args);
50 static double db0(double);
51 static double overflow(double);
52 static double nest1(int, double);
53 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     {0,0}
60 };
61 
62 static PyObject *test(PyObject *self,PyObject *args)
63 {
64     double r;
65 
66     fprintf(stderr,"overflow");
67     r = overflow(1.e160);
68     printerr(r);
69 
70     fprintf(stderr,"\ndiv by 0");
71     r = db0(0.0);
72     printerr(r);
73 
74     fprintf(stderr,"\nnested outer");
75     r = nest1(0, 0.0);
76     printerr(r);
77 
78     fprintf(stderr,"\nnested inner");
79     r = nest1(1, 1.0);
80     printerr(r);
81 
82     fprintf(stderr,"\ntrailing outer");
83     r = nest1(2, 2.0);
84     printerr(r);
85 
86     fprintf(stderr,"\nnested prior");
87     r = nest2(0, 0.0);
88     printerr(r);
89 
90     fprintf(stderr,"\nnested interior");
91     r = nest2(1, 1.0);
92     printerr(r);
93 
94     fprintf(stderr,"\nnested trailing");
95     r = nest2(2, 2.0);
96     printerr(r);
97 
98     Py_INCREF (Py_None);
99     return Py_None;
100 }
101 
102 static void printerr(double r)
103 {
104     if(r == 3.1416){
105       fprintf(stderr,"\tPASS\n");
106       PyErr_Print();
107     }else{
108       fprintf(stderr,"\tFAIL\n");
109     }
110     PyErr_Clear();
111 }
112 
113 static double nest1(int i, double x)
114 {
115   double a = 1.0;
116 
117   PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416)
118   if(i == 0){
119     a = 1./x;
120   }else if(i == 1){
121     /* This (following) message is never seen. */
122     PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416)
123     a = 1./(1. - x);
124     PyFPE_END_PROTECT(a)
125   }else if(i == 2){
126     a = 1./(2. - x);
127   }
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   PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416)
137   if(i == 0){
138     a = 1./x;
139   }else if(i == 1){
140     a = nest3(x);
141   }else if(i == 2){
142     a = 1./(2. - x);
143   }
144   PyFPE_END_PROTECT(a)
145   return a;
146 }
147 
148 static double nest3(double x)
149 {
150   double result;
151   /* This (following) message is never seen. */
152   PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416)
153   result = 1./(1. - x);
154   PyFPE_END_PROTECT(result)
155   return result;
156 }
157 
158 static double db0(double x)
159 {
160   double a;
161   PyFPE_START_PROTECT("Division by zero", return 3.1416)
162   a = 1./x;
163   PyFPE_END_PROTECT(a)
164   return a;
165 }
166 
167 static double overflow(double b)
168 {
169   double a;
170   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     PyModuleDef_HEAD_INIT,
178     "fpetest",
179     NULL,
180     -1,
181     fpetest_methods,
182     NULL,
183     NULL,
184     NULL,
185     NULL
186 };
187 
188 PyMODINIT_FUNC PyInit_fpetest(void)
189 {
190     PyObject *m, *d;
191 
192     m = PyModule_Create(&fpetestmodule);
193     if (m == NULL)
194     return NULL;
195     d = PyModule_GetDict(m);
196     fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
197     if (fpe_error != NULL)
198         PyDict_SetItemString(d, "error", fpe_error);
199     return m;
200 }
201