Bump version to 0.9.1.
[python/dscho.git] / Modules / mathmodule.c
blob626e606534bee44511e0e0fc1679573f08e8207c
1 /***********************************************************
2 Copyright (c) 2000, BeOpen.com.
3 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5 All rights reserved.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
11 /* Math module -- standard C math library functions, pi and e */
13 #include "Python.h"
15 #ifndef _MSC_VER
16 #ifndef __STDC__
17 extern double fmod (double, double);
18 extern double frexp (double, int *);
19 extern double ldexp (double, int);
20 extern double modf (double, double *);
21 #endif /* __STDC__ */
22 #endif /* _MSC_VER */
25 #ifdef i860
26 /* Cray APP has bogus definition of HUGE_VAL in <math.h> */
27 #undef HUGE_VAL
28 #endif
30 #ifdef HUGE_VAL
31 #define CHECK(x) if (errno != 0) ; \
32 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
33 else errno = ERANGE
34 #else
35 #define CHECK(x) /* Don't know how to check */
36 #endif
38 static PyObject *
39 math_error(void)
41 if (errno == EDOM)
42 PyErr_SetString(PyExc_ValueError, "math domain error");
43 else if (errno == ERANGE)
44 PyErr_SetString(PyExc_OverflowError, "math range error");
45 else
46 /* Unexpected math error */
47 PyErr_SetFromErrno(PyExc_ValueError);
48 return NULL;
51 static PyObject *
52 math_1(PyObject *args, double (*func) (double), char *argsfmt)
54 double x;
55 if (! PyArg_ParseTuple(args, argsfmt, &x))
56 return NULL;
57 errno = 0;
58 PyFPE_START_PROTECT("in math_1", return 0)
59 x = (*func)(x);
60 PyFPE_END_PROTECT(x)
61 CHECK(x);
62 if (errno != 0)
63 return math_error();
64 else
65 return PyFloat_FromDouble(x);
68 static PyObject *
69 math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
71 double x, y;
72 if (! PyArg_ParseTuple(args, argsfmt, &x, &y))
73 return NULL;
74 errno = 0;
75 PyFPE_START_PROTECT("in math_2", return 0)
76 x = (*func)(x, y);
77 PyFPE_END_PROTECT(x)
78 CHECK(x);
79 if (errno != 0)
80 return math_error();
81 else
82 return PyFloat_FromDouble(x);
85 #define FUNC1(funcname, func, docstring) \
86 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
87 return math_1(args, func, "d:" #funcname); \
89 static char math_##funcname##_doc [] = docstring;
91 #define FUNC2(funcname, func, docstring) \
92 static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
93 return math_2(args, func, "dd:" #funcname); \
95 static char math_##funcname##_doc [] = docstring;
97 FUNC1(acos, acos,
98 "acos(x)\n\nReturn the arc cosine of x.")
99 FUNC1(asin, asin,
100 "asin(x)\n\nReturn the arc sine of x.")
101 FUNC1(atan, atan,
102 "atan(x)\n\nReturn the arc tangent of x.")
103 FUNC2(atan2, atan2,
104 "atan2(y, x)\n\nReturn atan(y/x).")
105 FUNC1(ceil, ceil,
106 "ceil(x)\n\nReturn the ceiling of x as a real.")
107 FUNC1(cos, cos,
108 "cos(x)\n\nReturn the cosine of x.")
109 FUNC1(cosh, cosh,
110 "cosh(x)\n\nReturn the hyperbolic cosine of x.")
111 FUNC1(exp, exp,
112 "exp(x)\n\nReturn e raised to the power of x.")
113 FUNC1(fabs, fabs,
114 "fabs(x)\n\nReturn the absolute value of the real x.")
115 FUNC1(floor, floor,
116 "floor(x)\n\nReturn the floor of x as a real.")
117 FUNC2(fmod, fmod,
118 "fmod(x,y)\n\nReturn x % y.")
119 FUNC2(hypot, hypot,
120 "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
121 FUNC1(log, log,
122 "log(x)\n\nReturn the natural logarithm of x.")
123 FUNC1(log10, log10,
124 "log10(x)\n\nReturn the base-10 logarithm of x.")
125 #ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
126 FUNC2(pow, power,
127 "pow(x,y)\n\nReturn x**y.")
128 #else
129 FUNC2(pow, pow,
130 "pow(x,y)\n\nReturn x**y.")
131 #endif
132 FUNC1(sin, sin,
133 "sin(x)\n\nReturn the sine of x.")
134 FUNC1(sinh, sinh,
135 "sinh(x)\n\nReturn the hyperbolic sine of x.")
136 FUNC1(sqrt, sqrt,
137 "sqrt(x)\n\nReturn the square root of x.")
138 FUNC1(tan, tan,
139 "tan(x)\n\nReturn the tangent of x.")
140 FUNC1(tanh, tanh,
141 "tanh(x)\n\nReturn the hyperbolic tangent of x.")
144 static PyObject *
145 math_frexp(PyObject *self, PyObject *args)
147 double x;
148 int i;
149 if (! PyArg_ParseTuple(args, "d:frexp", &x))
150 return NULL;
151 errno = 0;
152 x = frexp(x, &i);
153 CHECK(x);
154 if (errno != 0)
155 return math_error();
156 return Py_BuildValue("(di)", x, i);
159 static char math_frexp_doc [] =
160 "frexp(x)\n\
162 Return the mantissa and exponent of x, as pair (m, e).\n\
163 m is a float and e is an int, such that x = m * 2.**e.\n\
164 If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.";
167 static PyObject *
168 math_ldexp(PyObject *self, PyObject *args)
170 double x;
171 int exp;
172 if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
173 return NULL;
174 errno = 0;
175 PyFPE_START_PROTECT("ldexp", return 0)
176 x = ldexp(x, exp);
177 PyFPE_END_PROTECT(x)
178 CHECK(x);
179 if (errno != 0)
180 return math_error();
181 else
182 return PyFloat_FromDouble(x);
185 static char math_ldexp_doc [] =
186 "ldexp_doc(x, i)\n\
188 Return x * (2**i).";
191 static PyObject *
192 math_modf(PyObject *self, PyObject *args)
194 double x, y;
195 if (! PyArg_ParseTuple(args, "d:modf", &x))
196 return NULL;
197 errno = 0;
198 #ifdef MPW /* MPW C modf expects pointer to extended as second argument */
200 extended e;
201 x = modf(x, &e);
202 y = e;
204 #else
205 x = modf(x, &y);
206 #endif
207 CHECK(x);
208 if (errno != 0)
209 return math_error();
210 return Py_BuildValue("(dd)", x, y);
213 static char math_modf_doc [] =
214 "modf(x)\n\
216 Return the fractional and integer parts of x. Both results carry the sign\n\
217 of x. The integer part is returned as a real.";
220 static PyMethodDef math_methods[] = {
221 {"acos", math_acos, METH_VARARGS, math_acos_doc},
222 {"asin", math_asin, METH_VARARGS, math_asin_doc},
223 {"atan", math_atan, METH_VARARGS, math_atan_doc},
224 {"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
225 {"ceil", math_ceil, METH_VARARGS, math_ceil_doc},
226 {"cos", math_cos, METH_VARARGS, math_cos_doc},
227 {"cosh", math_cosh, METH_VARARGS, math_cosh_doc},
228 {"exp", math_exp, METH_VARARGS, math_exp_doc},
229 {"fabs", math_fabs, METH_VARARGS, math_fabs_doc},
230 {"floor", math_floor, METH_VARARGS, math_floor_doc},
231 {"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
232 {"frexp", math_frexp, METH_VARARGS, math_frexp_doc},
233 {"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
234 {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
235 {"log", math_log, METH_VARARGS, math_log_doc},
236 {"log10", math_log10, METH_VARARGS, math_log10_doc},
237 {"modf", math_modf, METH_VARARGS, math_modf_doc},
238 {"pow", math_pow, METH_VARARGS, math_pow_doc},
239 {"sin", math_sin, METH_VARARGS, math_sin_doc},
240 {"sinh", math_sinh, METH_VARARGS, math_sinh_doc},
241 {"sqrt", math_sqrt, METH_VARARGS, math_sqrt_doc},
242 {"tan", math_tan, METH_VARARGS, math_tan_doc},
243 {"tanh", math_tanh, METH_VARARGS, math_tanh_doc},
244 {NULL, NULL} /* sentinel */
248 static char module_doc [] =
249 "This module is always available. It provides access to the\n\
250 mathematical functions defined by the C standard.";
252 DL_EXPORT(void)
253 initmath(void)
255 PyObject *m, *d, *v;
257 m = Py_InitModule3("math", math_methods, module_doc);
258 d = PyModule_GetDict(m);
260 if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
261 goto finally;
262 if (PyDict_SetItemString(d, "pi", v) < 0)
263 goto finally;
264 Py_DECREF(v);
266 if (!(v = PyFloat_FromDouble(exp(1.0))))
267 goto finally;
268 if (PyDict_SetItemString(d, "e", v) < 0)
269 goto finally;
270 Py_DECREF(v);
271 return;
273 finally:
274 Py_FatalError("can't initialize math module");