|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 } |