blob: 6e2d65bd02345e4d67829f90d3b1fd8732a4aab4 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Math module -- standard C math library functions, pi and e */
33
Barry Warsaw8b43b191996-12-09 22:32:36 +000034#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Barry Warsaw8b43b191996-12-09 22:32:36 +000036#define getdoublearg(v, a) PyArg_Parse(v, "d", a)
37#define get2doublearg(v, a, b) PyArg_Parse(v, "(dd)", a, b)
Guido van Rossum234f9421993-06-17 12:35:49 +000038
Guido van Rossum6964f731995-03-01 10:34:29 +000039#include "mymath.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000040
Guido van Rossum7081cf51996-05-23 22:56:19 +000041#ifndef _MSC_VER
Guido van Rossumb9418681995-01-12 11:28:16 +000042#ifndef __STDC__
Barry Warsaw8b43b191996-12-09 22:32:36 +000043extern double fmod Py_PROTO((double, double));
44extern double frexp Py_PROTO((double, int *));
45extern double ldexp Py_PROTO((double, int));
46extern double modf Py_PROTO((double, double *));
Guido van Rossum7081cf51996-05-23 22:56:19 +000047#endif /* __STDC__ */
48#endif /* _MSC_VER */
49
Guido van Rossumb9418681995-01-12 11:28:16 +000050
Guido van Rossum9575a441993-04-07 14:06:14 +000051#ifdef i860
52/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
53#undef HUGE_VAL
54#endif
55
Guido van Rossum8832b621991-12-16 15:44:24 +000056#ifdef HUGE_VAL
57#define CHECK(x) if (errno != 0) ; \
58 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
59 else errno = ERANGE
60#else
61#define CHECK(x) /* Don't know how to check */
62#endif
63
Barry Warsaw8b43b191996-12-09 22:32:36 +000064static PyObject *
Guido van Rossum8832b621991-12-16 15:44:24 +000065math_error()
66{
67 if (errno == EDOM)
Barry Warsaw8b43b191996-12-09 22:32:36 +000068 PyErr_SetString(PyExc_ValueError, "math domain error");
Guido van Rossum8832b621991-12-16 15:44:24 +000069 else if (errno == ERANGE)
Barry Warsaw8b43b191996-12-09 22:32:36 +000070 PyErr_SetString(PyExc_OverflowError, "math range error");
Guido van Rossum8832b621991-12-16 15:44:24 +000071 else
Barry Warsaw8b43b191996-12-09 22:32:36 +000072 /* Unexpected math error */
73 PyErr_SetFromErrno(PyExc_ValueError);
Guido van Rossum8832b621991-12-16 15:44:24 +000074 return NULL;
75}
76
Barry Warsaw8b43b191996-12-09 22:32:36 +000077static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078math_1(args, func)
Barry Warsaw8b43b191996-12-09 22:32:36 +000079 PyObject *args;
80 double (*func) Py_FPROTO((double));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081{
82 double x;
83 if (!getdoublearg(args, &x))
84 return NULL;
85 errno = 0;
86 x = (*func)(x);
Guido van Rossum8832b621991-12-16 15:44:24 +000087 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +000089 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 else
Barry Warsaw8b43b191996-12-09 22:32:36 +000091 return PyFloat_FromDouble(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092}
93
Barry Warsaw8b43b191996-12-09 22:32:36 +000094static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095math_2(args, func)
Barry Warsaw8b43b191996-12-09 22:32:36 +000096 PyObject *args;
97 double (*func) Py_FPROTO((double, double));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098{
99 double x, y;
100 if (!get2doublearg(args, &x, &y))
101 return NULL;
102 errno = 0;
103 x = (*func)(x, y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000104 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000106 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 else
Barry Warsaw8b43b191996-12-09 22:32:36 +0000108 return PyFloat_FromDouble(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109}
110
111#define FUNC1(stubname, func) \
Barry Warsaw8b43b191996-12-09 22:32:36 +0000112 static PyObject * stubname(self, args) PyObject *self, *args; { \
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 return math_1(args, func); \
114 }
115
116#define FUNC2(stubname, func) \
Barry Warsaw8b43b191996-12-09 22:32:36 +0000117 static PyObject * stubname(self, args) PyObject *self, *args; { \
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 return math_2(args, func); \
119 }
120
121FUNC1(math_acos, acos)
122FUNC1(math_asin, asin)
123FUNC1(math_atan, atan)
124FUNC2(math_atan2, atan2)
125FUNC1(math_ceil, ceil)
126FUNC1(math_cos, cos)
127FUNC1(math_cosh, cosh)
128FUNC1(math_exp, exp)
Guido van Rossum6412b1d1996-08-08 19:10:21 +0000129#ifdef __MWERKS__
130double myfabs(double x) { return fabs(x); }
131FUNC1(math_fabs, myfabs)
132#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133FUNC1(math_fabs, fabs)
Guido van Rossum6412b1d1996-08-08 19:10:21 +0000134#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135FUNC1(math_floor, floor)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136FUNC2(math_fmod, fmod)
Guido van Rossum411a8bd1994-10-20 22:00:28 +0000137FUNC2(math_hypot, hypot)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138FUNC1(math_log, log)
139FUNC1(math_log10, log10)
Guido van Rossum1492c271991-07-27 21:38:43 +0000140#ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000141FUNC2(math_pow, power)
142#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143FUNC2(math_pow, pow)
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000144#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145FUNC1(math_sin, sin)
146FUNC1(math_sinh, sinh)
147FUNC1(math_sqrt, sqrt)
148FUNC1(math_tan, tan)
149FUNC1(math_tanh, tanh)
150
Guido van Rossumb6775db1994-08-01 11:34:53 +0000151
Barry Warsaw8b43b191996-12-09 22:32:36 +0000152static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000153math_frexp(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000154 PyObject *self;
155 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000156{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000157 double x;
158 int i;
159 if (!getdoublearg(args, &x))
160 return NULL;
161 errno = 0;
162 x = frexp(x, &i);
Guido van Rossum8832b621991-12-16 15:44:24 +0000163 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000164 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000165 return math_error();
Barry Warsaw8b43b191996-12-09 22:32:36 +0000166 return Py_BuildValue("(di)", x, i);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000167}
168
Barry Warsaw8b43b191996-12-09 22:32:36 +0000169static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000170math_ldexp(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000171 PyObject *self;
172 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000173{
174 double x, y;
175 /* Cheat -- allow float as second argument */
176 if (!get2doublearg(args, &x, &y))
177 return NULL;
178 errno = 0;
179 x = ldexp(x, (int)y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000180 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000181 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000182 return math_error();
Guido van Rossumd18ad581991-10-24 14:57:21 +0000183 else
Barry Warsaw8b43b191996-12-09 22:32:36 +0000184 return PyFloat_FromDouble(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000185}
186
Barry Warsaw8b43b191996-12-09 22:32:36 +0000187static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000188math_modf(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000189 PyObject *self;
190 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000191{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000192 double x, y;
193 if (!getdoublearg(args, &x))
194 return NULL;
195 errno = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
197{
198 extended e;
199 x = modf(x, &e);
200 y = e;
201}
202#else
Guido van Rossumd18ad581991-10-24 14:57:21 +0000203 x = modf(x, &y);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#endif
Guido van Rossum8832b621991-12-16 15:44:24 +0000205 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000206 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000207 return math_error();
Barry Warsaw8b43b191996-12-09 22:32:36 +0000208 return Py_BuildValue("(dd)", x, y);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000209}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210
Barry Warsaw8b43b191996-12-09 22:32:36 +0000211static PyMethodDef math_methods[] = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 {"acos", math_acos},
213 {"asin", math_asin},
214 {"atan", math_atan},
215 {"atan2", math_atan2},
216 {"ceil", math_ceil},
217 {"cos", math_cos},
218 {"cosh", math_cosh},
219 {"exp", math_exp},
220 {"fabs", math_fabs},
221 {"floor", math_floor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 {"fmod", math_fmod},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000223 {"frexp", math_frexp},
Guido van Rossum411a8bd1994-10-20 22:00:28 +0000224 {"hypot", math_hypot},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000225 {"ldexp", math_ldexp},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 {"log", math_log},
227 {"log10", math_log10},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 {"modf", math_modf},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 {"pow", math_pow},
230 {"sin", math_sin},
231 {"sinh", math_sinh},
232 {"sqrt", math_sqrt},
233 {"tan", math_tan},
234 {"tanh", math_tanh},
235 {NULL, NULL} /* sentinel */
236};
237
238void
239initmath()
240{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000241 PyObject *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000242
Barry Warsaw8b43b191996-12-09 22:32:36 +0000243 m = Py_InitModule("math", math_methods);
244 d = PyModule_GetDict(m);
245 PyDict_SetItemString(d, "pi", v = PyFloat_FromDouble(atan(1.0) * 4.0));
246 Py_DECREF(v);
247 PyDict_SetItemString(d, "e", v = PyFloat_FromDouble(exp(1.0)));
248 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249}