source: vendor/python/2.5/Modules/mathmodule.c

Last change on this file was 3225, checked in by bird, 18 years ago

Python 2.5

File size: 10.5 KB
Line 
1/* Math module -- standard C math library functions, pi and e */
2
3#include "Python.h"
4#include "longintrepr.h" /* just for SHIFT */
5
6#ifndef _MSC_VER
7#ifndef __STDC__
8extern double fmod (double, double);
9extern double frexp (double, int *);
10extern double ldexp (double, int);
11extern double modf (double, double *);
12#endif /* __STDC__ */
13#endif /* _MSC_VER */
14
15/* Call is_error when errno != 0, and where x is the result libm
16 * returned. is_error will usually set up an exception and return
17 * true (1), but may return false (0) without setting up an exception.
18 */
19static int
20is_error(double x)
21{
22 int result = 1; /* presumption of guilt */
23 assert(errno); /* non-zero errno is a precondition for calling */
24 if (errno == EDOM)
25 PyErr_SetString(PyExc_ValueError, "math domain error");
26
27 else if (errno == ERANGE) {
28 /* ANSI C generally requires libm functions to set ERANGE
29 * on overflow, but also generally *allows* them to set
30 * ERANGE on underflow too. There's no consistency about
31 * the latter across platforms.
32 * Alas, C99 never requires that errno be set.
33 * Here we suppress the underflow errors (libm functions
34 * should return a zero on underflow, and +- HUGE_VAL on
35 * overflow, so testing the result for zero suffices to
36 * distinguish the cases).
37 */
38 if (x)
39 PyErr_SetString(PyExc_OverflowError,
40 "math range error");
41 else
42 result = 0;
43 }
44 else
45 /* Unexpected math error */
46 PyErr_SetFromErrno(PyExc_ValueError);
47 return result;
48}
49
50static PyObject *
51math_1(PyObject *args, double (*func) (double), char *argsfmt)
52{
53 double x;
54 if (! PyArg_ParseTuple(args, argsfmt, &x))
55 return NULL;
56 errno = 0;
57 PyFPE_START_PROTECT("in math_1", return 0)
58 x = (*func)(x);
59 PyFPE_END_PROTECT(x)
60 Py_SET_ERRNO_ON_MATH_ERROR(x);
61 if (errno && is_error(x))
62 return NULL;
63 else
64 return PyFloat_FromDouble(x);
65}
66
67static PyObject *
68math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
69{
70 double x, y;
71 if (! PyArg_ParseTuple(args, argsfmt, &x, &y))
72 return NULL;
73 errno = 0;
74 PyFPE_START_PROTECT("in math_2", return 0)
75 x = (*func)(x, y);
76 PyFPE_END_PROTECT(x)
77 Py_SET_ERRNO_ON_MATH_ERROR(x);
78 if (errno && is_error(x))
79 return NULL;
80 else
81 return PyFloat_FromDouble(x);
82}
83
84#define FUNC1(funcname, func, docstring) \
85 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
86 return math_1(args, func, "d:" #funcname); \
87 }\
88 PyDoc_STRVAR(math_##funcname##_doc, docstring);
89
90#define FUNC2(funcname, func, docstring) \
91 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
92 return math_2(args, func, "dd:" #funcname); \
93 }\
94 PyDoc_STRVAR(math_##funcname##_doc, docstring);
95
96FUNC1(acos, acos,
97 "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
98FUNC1(asin, asin,
99 "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
100FUNC1(atan, atan,
101 "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
102FUNC2(atan2, atan2,
103 "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
104 "Unlike atan(y/x), the signs of both x and y are considered.")
105FUNC1(ceil, ceil,
106 "ceil(x)\n\nReturn the ceiling of x as a float.\n"
107 "This is the smallest integral value >= x.")
108FUNC1(cos, cos,
109 "cos(x)\n\nReturn the cosine of x (measured in radians).")
110FUNC1(cosh, cosh,
111 "cosh(x)\n\nReturn the hyperbolic cosine of x.")
112FUNC1(exp, exp,
113 "exp(x)\n\nReturn e raised to the power of x.")
114FUNC1(fabs, fabs,
115 "fabs(x)\n\nReturn the absolute value of the float x.")
116FUNC1(floor, floor,
117 "floor(x)\n\nReturn the floor of x as a float.\n"
118 "This is the largest integral value <= x.")
119FUNC2(fmod, fmod,
120 "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
121 " x % y may differ.")
122FUNC2(hypot, hypot,
123 "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
124FUNC2(pow, pow,
125 "pow(x,y)\n\nReturn x**y (x to the power of y).")
126FUNC1(sin, sin,
127 "sin(x)\n\nReturn the sine of x (measured in radians).")
128FUNC1(sinh, sinh,
129 "sinh(x)\n\nReturn the hyperbolic sine of x.")
130FUNC1(sqrt, sqrt,
131 "sqrt(x)\n\nReturn the square root of x.")
132FUNC1(tan, tan,
133 "tan(x)\n\nReturn the tangent of x (measured in radians).")
134FUNC1(tanh, tanh,
135 "tanh(x)\n\nReturn the hyperbolic tangent of x.")
136
137static PyObject *
138math_frexp(PyObject *self, PyObject *args)
139{
140 double x;
141 int i;
142 if (! PyArg_ParseTuple(args, "d:frexp", &x))
143 return NULL;
144 errno = 0;
145 x = frexp(x, &i);
146 Py_SET_ERRNO_ON_MATH_ERROR(x);
147 if (errno && is_error(x))
148 return NULL;
149 else
150 return Py_BuildValue("(di)", x, i);
151}
152
153PyDoc_STRVAR(math_frexp_doc,
154"frexp(x)\n"
155"\n"
156"Return the mantissa and exponent of x, as pair (m, e).\n"
157"m is a float and e is an int, such that x = m * 2.**e.\n"
158"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
159
160static PyObject *
161math_ldexp(PyObject *self, PyObject *args)
162{
163 double x;
164 int exp;
165 if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
166 return NULL;
167 errno = 0;
168 PyFPE_START_PROTECT("ldexp", return 0)
169 x = ldexp(x, exp);
170 PyFPE_END_PROTECT(x)
171 Py_SET_ERRNO_ON_MATH_ERROR(x);
172 if (errno && is_error(x))
173 return NULL;
174 else
175 return PyFloat_FromDouble(x);
176}
177
178PyDoc_STRVAR(math_ldexp_doc,
179"ldexp(x, i) -> x * (2**i)");
180
181static PyObject *
182math_modf(PyObject *self, PyObject *args)
183{
184 double x, y;
185 if (! PyArg_ParseTuple(args, "d:modf", &x))
186 return NULL;
187 errno = 0;
188 x = modf(x, &y);
189 Py_SET_ERRNO_ON_MATH_ERROR(x);
190 if (errno && is_error(x))
191 return NULL;
192 else
193 return Py_BuildValue("(dd)", x, y);
194}
195
196PyDoc_STRVAR(math_modf_doc,
197"modf(x)\n"
198"\n"
199"Return the fractional and integer parts of x. Both results carry the sign\n"
200"of x. The integer part is returned as a real.");
201
202/* A decent logarithm is easy to compute even for huge longs, but libm can't
203 do that by itself -- loghelper can. func is log or log10, and name is
204 "log" or "log10". Note that overflow isn't possible: a long can contain
205 no more than INT_MAX * SHIFT bits, so has value certainly less than
206 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
207 small enough to fit in an IEEE single. log and log10 are even smaller.
208*/
209
210static PyObject*
211loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg)
212{
213 /* If it is long, do it ourselves. */
214 if (PyLong_Check(arg)) {
215 double x;
216 int e;
217 x = _PyLong_AsScaledDouble(arg, &e);
218 if (x <= 0.0) {
219 PyErr_SetString(PyExc_ValueError,
220 "math domain error");
221 return NULL;
222 }
223 /* Value is ~= x * 2**(e*SHIFT), so the log ~=
224 log(x) + log(2) * e * SHIFT.
225 CAUTION: e*SHIFT may overflow using int arithmetic,
226 so force use of double. */
227 x = func(x) + (e * (double)SHIFT) * func(2.0);
228 return PyFloat_FromDouble(x);
229 }
230
231 /* Else let libm handle it by itself. */
232 return math_1(args, func, format);
233}
234
235static PyObject *
236math_log(PyObject *self, PyObject *args)
237{
238 PyObject *arg;
239 PyObject *base = NULL;
240 PyObject *num, *den;
241 PyObject *ans;
242 PyObject *newargs;
243
244 if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
245 return NULL;
246 if (base == NULL)
247 return loghelper(args, log, "d:log", arg);
248
249 newargs = PyTuple_Pack(1, arg);
250 if (newargs == NULL)
251 return NULL;
252 num = loghelper(newargs, log, "d:log", arg);
253 Py_DECREF(newargs);
254 if (num == NULL)
255 return NULL;
256
257 newargs = PyTuple_Pack(1, base);
258 if (newargs == NULL) {
259 Py_DECREF(num);
260 return NULL;
261 }
262 den = loghelper(newargs, log, "d:log", base);
263 Py_DECREF(newargs);
264 if (den == NULL) {
265 Py_DECREF(num);
266 return NULL;
267 }
268
269 ans = PyNumber_Divide(num, den);
270 Py_DECREF(num);
271 Py_DECREF(den);
272 return ans;
273}
274
275PyDoc_STRVAR(math_log_doc,
276"log(x[, base]) -> the logarithm of x to the given base.\n\
277If the base not specified, returns the natural logarithm (base e) of x.");
278
279static PyObject *
280math_log10(PyObject *self, PyObject *args)
281{
282 PyObject *arg;
283
284 if (!PyArg_UnpackTuple(args, "log10", 1, 1, &arg))
285 return NULL;
286 return loghelper(args, log10, "d:log10", arg);
287}
288
289PyDoc_STRVAR(math_log10_doc,
290"log10(x) -> the base 10 logarithm of x.");
291
292static const double degToRad = 3.141592653589793238462643383 / 180.0;
293
294static PyObject *
295math_degrees(PyObject *self, PyObject *args)
296{
297 double x;
298 if (! PyArg_ParseTuple(args, "d:degrees", &x))
299 return NULL;
300 return PyFloat_FromDouble(x / degToRad);
301}
302
303PyDoc_STRVAR(math_degrees_doc,
304"degrees(x) -> converts angle x from radians to degrees");
305
306static PyObject *
307math_radians(PyObject *self, PyObject *args)
308{
309 double x;
310 if (! PyArg_ParseTuple(args, "d:radians", &x))
311 return NULL;
312 return PyFloat_FromDouble(x * degToRad);
313}
314
315PyDoc_STRVAR(math_radians_doc,
316"radians(x) -> converts angle x from degrees to radians");
317
318static PyMethodDef math_methods[] = {
319 {"acos", math_acos, METH_VARARGS, math_acos_doc},
320 {"asin", math_asin, METH_VARARGS, math_asin_doc},
321 {"atan", math_atan, METH_VARARGS, math_atan_doc},
322 {"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
323 {"ceil", math_ceil, METH_VARARGS, math_ceil_doc},
324 {"cos", math_cos, METH_VARARGS, math_cos_doc},
325 {"cosh", math_cosh, METH_VARARGS, math_cosh_doc},
326 {"degrees", math_degrees, METH_VARARGS, math_degrees_doc},
327 {"exp", math_exp, METH_VARARGS, math_exp_doc},
328 {"fabs", math_fabs, METH_VARARGS, math_fabs_doc},
329 {"floor", math_floor, METH_VARARGS, math_floor_doc},
330 {"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
331 {"frexp", math_frexp, METH_VARARGS, math_frexp_doc},
332 {"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
333 {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
334 {"log", math_log, METH_VARARGS, math_log_doc},
335 {"log10", math_log10, METH_VARARGS, math_log10_doc},
336 {"modf", math_modf, METH_VARARGS, math_modf_doc},
337 {"pow", math_pow, METH_VARARGS, math_pow_doc},
338 {"radians", math_radians, METH_VARARGS, math_radians_doc},
339 {"sin", math_sin, METH_VARARGS, math_sin_doc},
340 {"sinh", math_sinh, METH_VARARGS, math_sinh_doc},
341 {"sqrt", math_sqrt, METH_VARARGS, math_sqrt_doc},
342 {"tan", math_tan, METH_VARARGS, math_tan_doc},
343 {"tanh", math_tanh, METH_VARARGS, math_tanh_doc},
344 {NULL, NULL} /* sentinel */
345};
346
347
348PyDoc_STRVAR(module_doc,
349"This module is always available. It provides access to the\n"
350"mathematical functions defined by the C standard.");
351
352PyMODINIT_FUNC
353initmath(void)
354{
355 PyObject *m, *d, *v;
356
357 m = Py_InitModule3("math", math_methods, module_doc);
358 if (m == NULL)
359 goto finally;
360 d = PyModule_GetDict(m);
361
362 if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
363 goto finally;
364 if (PyDict_SetItemString(d, "pi", v) < 0)
365 goto finally;
366 Py_DECREF(v);
367
368 if (!(v = PyFloat_FromDouble(exp(1.0))))
369 goto finally;
370 if (PyDict_SetItemString(d, "e", v) < 0)
371 goto finally;
372 Py_DECREF(v);
373
374 finally:
375 return;
376}
Note: See TracBrowser for help on using the repository browser.