blob: 1c6b144ff42e904e315885fe041702962b43ebd7 [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
Guido van Rossum6964f731995-03-01 10:34:29 +000036#include "mymath.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000037
Guido van Rossum7081cf51996-05-23 22:56:19 +000038#ifndef _MSC_VER
Guido van Rossumb9418681995-01-12 11:28:16 +000039#ifndef __STDC__
Barry Warsaw8b43b191996-12-09 22:32:36 +000040extern double fmod Py_PROTO((double, double));
41extern double frexp Py_PROTO((double, int *));
42extern double ldexp Py_PROTO((double, int));
43extern double modf Py_PROTO((double, double *));
Guido van Rossum7081cf51996-05-23 22:56:19 +000044#endif /* __STDC__ */
45#endif /* _MSC_VER */
46
Guido van Rossumb9418681995-01-12 11:28:16 +000047
Guido van Rossum9575a441993-04-07 14:06:14 +000048#ifdef i860
49/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
50#undef HUGE_VAL
51#endif
52
Guido van Rossum8832b621991-12-16 15:44:24 +000053#ifdef HUGE_VAL
54#define CHECK(x) if (errno != 0) ; \
55 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
56 else errno = ERANGE
57#else
58#define CHECK(x) /* Don't know how to check */
59#endif
60
Barry Warsaw8b43b191996-12-09 22:32:36 +000061static PyObject *
Guido van Rossum8832b621991-12-16 15:44:24 +000062math_error()
63{
64 if (errno == EDOM)
Barry Warsaw8b43b191996-12-09 22:32:36 +000065 PyErr_SetString(PyExc_ValueError, "math domain error");
Guido van Rossum8832b621991-12-16 15:44:24 +000066 else if (errno == ERANGE)
Barry Warsaw8b43b191996-12-09 22:32:36 +000067 PyErr_SetString(PyExc_OverflowError, "math range error");
Guido van Rossum8832b621991-12-16 15:44:24 +000068 else
Barry Warsaw8b43b191996-12-09 22:32:36 +000069 /* Unexpected math error */
70 PyErr_SetFromErrno(PyExc_ValueError);
Guido van Rossum8832b621991-12-16 15:44:24 +000071 return NULL;
72}
73
Barry Warsaw8b43b191996-12-09 22:32:36 +000074static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075math_1(args, func)
Barry Warsaw8b43b191996-12-09 22:32:36 +000076 PyObject *args;
77 double (*func) Py_FPROTO((double));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078{
79 double x;
Roger E. Masse20c63811996-12-18 21:59:01 +000080 if (! PyArg_Parse(args, "d", &x))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081 return NULL;
82 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +000083 PyFPE_START_PROTECT("in math_1", return 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 x = (*func)(x);
Guido van Rossum45b83911997-03-14 04:32:50 +000085 PyFPE_END_PROTECT(x)
Guido van Rossum8832b621991-12-16 15:44:24 +000086 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +000088 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 else
Barry Warsaw8b43b191996-12-09 22:32:36 +000090 return PyFloat_FromDouble(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091}
92
Barry Warsaw8b43b191996-12-09 22:32:36 +000093static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094math_2(args, func)
Barry Warsaw8b43b191996-12-09 22:32:36 +000095 PyObject *args;
96 double (*func) Py_FPROTO((double, double));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097{
98 double x, y;
Roger E. Masse20c63811996-12-18 21:59:01 +000099 if (! PyArg_Parse(args, "(dd)", &x, &y))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 return NULL;
101 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000102 PyFPE_START_PROTECT("in math_2", return 0)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 x = (*func)(x, y);
Guido van Rossum45b83911997-03-14 04:32:50 +0000104 PyFPE_END_PROTECT(x)
Guido van Rossum8832b621991-12-16 15:44:24 +0000105 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000107 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108 else
Barry Warsaw8b43b191996-12-09 22:32:36 +0000109 return PyFloat_FromDouble(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110}
111
Guido van Rossumc6e22901998-12-04 19:26:43 +0000112#define FUNC1(stubname, func, docstring_name, docstring) \
Barry Warsaw8b43b191996-12-09 22:32:36 +0000113 static PyObject * stubname(self, args) PyObject *self, *args; { \
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 return math_1(args, func); \
Guido van Rossumc6e22901998-12-04 19:26:43 +0000115 }\
116 static char docstring_name [] = docstring;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117
Guido van Rossumc6e22901998-12-04 19:26:43 +0000118#define FUNC2(stubname, func, docstring_name, docstring) \
Barry Warsaw8b43b191996-12-09 22:32:36 +0000119 static PyObject * stubname(self, args) PyObject *self, *args; { \
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 return math_2(args, func); \
Guido van Rossumc6e22901998-12-04 19:26:43 +0000121 }\
122 static char docstring_name [] = docstring;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123
Guido van Rossumc6e22901998-12-04 19:26:43 +0000124FUNC1(math_acos, acos, math_acos_doc,
125 "acos(x)\n\nReturn the arc cosine of x.")
126FUNC1(math_asin, asin, math_asin_doc,
127 "asin(x)\n\nReturn the arc sine of x.")
128FUNC1(math_atan, atan, math_atan_doc,
129 "atan(x)\n\nReturn the arc tangent of x.")
130FUNC2(math_atan2, atan2, math_atan2_doc,
Guido van Rossumb057dd81998-12-08 16:27:10 +0000131 "atan2(y, x)\n\nReturn atan(y/x).")
Guido van Rossumc6e22901998-12-04 19:26:43 +0000132FUNC1(math_ceil, ceil, math_ceil_doc,
133 "ceil(x)\n\nReturn the ceiling of x as a real.")
134FUNC1(math_cos, cos, math_cos_doc,
135 "cos(x)\n\nReturn the cosine of x.")
136FUNC1(math_cosh, cosh, math_cosh_doc,
137 "cosh(x)\n\nReturn the hyperbolic cosine of x.")
138FUNC1(math_exp, exp, math_exp_doc,
139 "exp(x)\n\nReturn e raised to the power of x.")
140FUNC1(math_fabs, fabs, math_fabs_doc,
141 "fabs(x)\n\nReturn the absolute value of the real x.")
142FUNC1(math_floor, floor, math_floor_doc,
143 "floor(x)\n\nReturn the floor of x as a real.")
144FUNC2(math_fmod, fmod, math_fmod_doc,
145 "fmod(x,y)\n\nReturn x % y.")
146FUNC2(math_hypot, hypot, math_hypot_doc,
147 "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
148FUNC1(math_log, log, math_log_doc,
149 "log(x)\n\nReturn the natural logarithm of x.")
150FUNC1(math_log10, log10, math_log10_doc,
151 "log10(x)\n\nReturn the base-10 logarithm of x.")
Guido van Rossum1492c271991-07-27 21:38:43 +0000152#ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
Guido van Rossumc6e22901998-12-04 19:26:43 +0000153FUNC2(math_pow, power, math_pow_doc,
154 "power(x,y)\n\nReturn x**y.")
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000155#else
Guido van Rossumc6e22901998-12-04 19:26:43 +0000156FUNC2(math_pow, pow, math_pow_doc,
157 "pow(x,y)\n\nReturn x**y.")
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000158#endif
Guido van Rossumc9a5f342000-05-11 18:42:27 +0000159#ifdef HAVE_RINT
Guido van Rossum71260b82000-05-11 18:19:42 +0000160FUNC1(math_rint, rint, math_rint_doc,
161 "rint(x)\n\nReturn the integer nearest to x as a real.")
Guido van Rossumc9a5f342000-05-11 18:42:27 +0000162#endif
Guido van Rossumc6e22901998-12-04 19:26:43 +0000163FUNC1(math_sin, sin, math_sin_doc,
164 "sin(x)\n\nReturn the sine of x.")
165FUNC1(math_sinh, sinh, math_sinh_doc,
166 "sinh(x)\n\nReturn the hyperbolic sine of x.")
167FUNC1(math_sqrt, sqrt, math_sqrt_doc,
168 "sqrt(x)\n\nReturn the square root of x.")
169FUNC1(math_tan, tan, math_tan_doc,
170 "tan(x)\n\nReturn the tangent of x.")
171FUNC1(math_tanh, tanh, math_tanh_doc,
172 "tanh(x)\n\nReturn the hyperbolic tangent of x.")
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174
Barry Warsaw8b43b191996-12-09 22:32:36 +0000175static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000176math_frexp(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000177 PyObject *self;
178 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000179{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000180 double x;
181 int i;
Roger E. Masse20c63811996-12-18 21:59:01 +0000182 if (! PyArg_Parse(args, "d", &x))
Guido van Rossumd18ad581991-10-24 14:57:21 +0000183 return NULL;
184 errno = 0;
185 x = frexp(x, &i);
Guido van Rossum8832b621991-12-16 15:44:24 +0000186 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000187 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000188 return math_error();
Barry Warsaw8b43b191996-12-09 22:32:36 +0000189 return Py_BuildValue("(di)", x, i);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000190}
191
Guido van Rossumc6e22901998-12-04 19:26:43 +0000192static char math_frexp_doc [] =
193"frexp(x)\n\
194\n\
195Return the matissa and exponent for x. The mantissa is positive.";
196
197
Barry Warsaw8b43b191996-12-09 22:32:36 +0000198static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000199math_ldexp(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000200 PyObject *self;
201 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000202{
Guido van Rossumc5545052000-05-08 14:29:38 +0000203 double x;
204 int exp;
205 if (! PyArg_Parse(args, "(di)", &x, &exp))
Guido van Rossumd18ad581991-10-24 14:57:21 +0000206 return NULL;
207 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000208 PyFPE_START_PROTECT("ldexp", return 0)
Guido van Rossumc5545052000-05-08 14:29:38 +0000209 x = ldexp(x, exp);
Guido van Rossum45b83911997-03-14 04:32:50 +0000210 PyFPE_END_PROTECT(x)
Guido van Rossum8832b621991-12-16 15:44:24 +0000211 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000212 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000213 return math_error();
Guido van Rossumd18ad581991-10-24 14:57:21 +0000214 else
Barry Warsaw8b43b191996-12-09 22:32:36 +0000215 return PyFloat_FromDouble(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000216}
217
Guido van Rossumc6e22901998-12-04 19:26:43 +0000218static char math_ldexp_doc [] =
219"ldexp_doc(x, i)\n\
220\n\
221Return x * (2**i).";
222
223
Barry Warsaw8b43b191996-12-09 22:32:36 +0000224static PyObject *
Guido van Rossumd18ad581991-10-24 14:57:21 +0000225math_modf(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000226 PyObject *self;
227 PyObject *args;
Guido van Rossumd18ad581991-10-24 14:57:21 +0000228{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000229 double x, y;
Roger E. Masse20c63811996-12-18 21:59:01 +0000230 if (! PyArg_Parse(args, "d", &x))
Guido van Rossumd18ad581991-10-24 14:57:21 +0000231 return NULL;
232 errno = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
234{
235 extended e;
236 x = modf(x, &e);
237 y = e;
238}
239#else
Guido van Rossumd18ad581991-10-24 14:57:21 +0000240 x = modf(x, &y);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#endif
Guido van Rossum8832b621991-12-16 15:44:24 +0000242 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000243 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000244 return math_error();
Barry Warsaw8b43b191996-12-09 22:32:36 +0000245 return Py_BuildValue("(dd)", x, y);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000246}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Guido van Rossumc6e22901998-12-04 19:26:43 +0000248static char math_modf_doc [] =
249"modf(x)\n\
250\n\
251Return the fractional and integer parts of x. Both results carry the sign\n\
252of x. The integer part is returned as a real.";
253
254
Barry Warsaw8b43b191996-12-09 22:32:36 +0000255static PyMethodDef math_methods[] = {
Guido van Rossumc6e22901998-12-04 19:26:43 +0000256 {"acos", math_acos, 0, math_acos_doc},
257 {"asin", math_asin, 0, math_asin_doc},
258 {"atan", math_atan, 0, math_atan_doc},
259 {"atan2", math_atan2, 0, math_atan2_doc},
260 {"ceil", math_ceil, 0, math_ceil_doc},
261 {"cos", math_cos, 0, math_cos_doc},
262 {"cosh", math_cosh, 0, math_cosh_doc},
263 {"exp", math_exp, 0, math_exp_doc},
264 {"fabs", math_fabs, 0, math_fabs_doc},
265 {"floor", math_floor, 0, math_floor_doc},
266 {"fmod", math_fmod, 0, math_fmod_doc},
267 {"frexp", math_frexp, 0, math_frexp_doc},
268 {"hypot", math_hypot, 0, math_hypot_doc},
269 {"ldexp", math_ldexp, 0, math_ldexp_doc},
270 {"log", math_log, 0, math_log_doc},
271 {"log10", math_log10, 0, math_log10_doc},
272 {"modf", math_modf, 0, math_modf_doc},
273 {"pow", math_pow, 0, math_pow_doc},
Guido van Rossumc9a5f342000-05-11 18:42:27 +0000274#ifdef HAVE_RINT
Guido van Rossum71260b82000-05-11 18:19:42 +0000275 {"rint", math_rint, 0, math_rint_doc},
Guido van Rossumc9a5f342000-05-11 18:42:27 +0000276#endif
Guido van Rossumc6e22901998-12-04 19:26:43 +0000277 {"sin", math_sin, 0, math_sin_doc},
278 {"sinh", math_sinh, 0, math_sinh_doc},
279 {"sqrt", math_sqrt, 0, math_sqrt_doc},
280 {"tan", math_tan, 0, math_tan_doc},
281 {"tanh", math_tanh, 0, math_tanh_doc},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282 {NULL, NULL} /* sentinel */
283};
284
Guido van Rossumc6e22901998-12-04 19:26:43 +0000285
286static char module_doc [] =
287"This module is always available. It provides access to the\n\
288mathematical functions defined by the C standard.";
289
Guido van Rossum3886bb61998-12-04 18:50:17 +0000290DL_EXPORT(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291initmath()
292{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000293 PyObject *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000294
Guido van Rossumc6e22901998-12-04 19:26:43 +0000295 m = Py_InitModule3("math", math_methods, module_doc);
Barry Warsaw8b43b191996-12-09 22:32:36 +0000296 d = PyModule_GetDict(m);
Barry Warsawfc93f751996-12-17 00:47:03 +0000297
298 if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
299 goto finally;
300 if (PyDict_SetItemString(d, "pi", v) < 0)
301 goto finally;
Barry Warsaw8b43b191996-12-09 22:32:36 +0000302 Py_DECREF(v);
Barry Warsawfc93f751996-12-17 00:47:03 +0000303
304 if (!(v = PyFloat_FromDouble(exp(1.0))))
305 goto finally;
Guido van Rossum4c4cbf31996-12-18 14:12:22 +0000306 if (PyDict_SetItemString(d, "e", v) < 0)
Barry Warsawfc93f751996-12-17 00:47:03 +0000307 goto finally;
Barry Warsaw8b43b191996-12-09 22:32:36 +0000308 Py_DECREF(v);
Guido van Rossum4a488091996-12-18 14:14:33 +0000309 return;
Barry Warsawfc93f751996-12-17 00:47:03 +0000310
311 finally:
312 Py_FatalError("can't initialize math module");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313}